Translate

Mostrando las entradas para la consulta gleam ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas
Mostrando las entradas para la consulta gleam ordenadas por relevancia. Ordenar por fecha Mostrar todas las entradas

jueves, 9 de marzo de 2023

Gleam, un lenguaje funcional que corre en la Vm de Erlang.


Gleam es un lenguaje funcional que corre sobre la maquina virtual de Erlang. Es de tipado estatico, funcional y sintaxis similar a Erlang y Elixir.   

Gleam se ejecuta en la máquina virtual Erlang que impulsa sistemas a escala planetaria como WhatsApp y Ericsson, está listo para cargas de trabajo de cualquier tamaño. Gracias a un sistema de simultaneidad basado en múltiples núcleos que puede ejecutar millones de tareas simultáneas, estructuras de datos rápidas e inmutables y un recolector de basura simultáneo, su servicio puede escalar y mantenerse con facilidad.

Gleam viene con compilador, herramienta de compilación, formateador, integraciones de editor y administrador de paquetes, todo integrado, por lo que crear un proyecto Gleam es simplemente ejecutar gleam new.

Como parte del ecosistema BEAM más amplio, los programas Gleam pueden usar miles de paquetes publicados, ya sea que estén escritos en Gleam, Erlang o Elixir.

Sin valores nulos, sin excepciones, mensajes de error claros y un sistema de tipo práctico. Ya sea que esté escribiendo código nuevo o manteniendo código antiguo, Gleam está diseñado para hacer que su trabajo sea lo más divertido y libre de estrés posible.

Gleam también puede compilar en JavaScript, lo que le permite usar su código en el navegador o en cualquier otro lugar donde se pueda ejecutar JavaScript. También genera definiciones de TypeScript, por lo que puede interactuar con su código Gleam con confianza, incluso desde el exterior.


Veamos un pequeño hola mundo hecho en Gleam:

import gleam/io


pub fn main() {

  io.println("hello, friend!")

}


Por ejemplo veamos código asincrono: 


fn spawn_task(i) {

  task.async(fn() {

    let n = int.to_string(i)

    io.println("Hello from " <> n)

  })

}


pub fn main() {

  // Run a million threads, no problem

    list.range(0, 1_000_000)

  |> list.map(spawn_task)

  |> list.each(task.await_forever)

}

Dejo link: https://gleam.run/

miércoles, 9 de octubre de 2024

Externals en Gleam


import gleam/io


// A type with no Gleam constructors

pub type DateTime


// An external function that creates an instance of the type

@external(javascript, "./my_package_ffi.mjs", "now")

pub fn now() -> DateTime


// The `now` function in `./my_package_ffi.mjs` looks like this:

// export function now() {

//   return new Date();

// }


pub fn main() {

  io.debug(now())

}


El resultado es : 

//js(Date("2024-10-05T17:29:39.958Z"))


A veces, en nuestros proyectos, queremos usar código escrito en otros lenguajes, más comúnmente Erlang y JavaScript, dependiendo del entorno de ejecución que se esté usando. Las funciones externas y los tipos externos de Gleam nos permiten importar y usar este código que no es de Gleam.

Un tipo externo es aquel que no tiene constructores. Gleam no sabe qué forma tiene ni cómo crear uno, solo sabe que existe.

Una función externa es aquella que tiene el atributo @external, que indica al compilador que use la función del módulo especificado como implementación, en lugar del código de Gleam.

El compilador no puede determinar los tipos de funciones escritas en otros lenguajes, por lo que cuando se proporciona el atributo externo, se deben proporcionar anotaciones de tipo. Gleam confía en que el tipo proporcionado sea correcto, por lo que una anotación de tipo inexacta puede generar un comportamiento inesperado y fallas en el entorno de ejecución. ¡Ten cuidado!

Las funciones externas son útiles, pero se deben usar con moderación. Es preferible escribir código de Gleam cuando sea posible.

viernes, 1 de marzo de 2024

Sistema de tipo en Gleam


 import gleam/io


pub fn main() {

  io.println("My lucky number is:")

  // io.println(4)

}



Gleam tiene un robusto sistema de tipos estáticos que ayuda a escribir y editar código, detectando errores y mostrándole dónde realizar cambios.

Si descomentamos la línea io.println(4), Gleam lanza el siguiente error:


error: Type mismatch

  ┌─ /src/main.gleam:5:14

  │

5 │   io.println(4)

  │              ^


Expected type:


    String


Found type:


    Int


Para corregir el código, podemos cambiar  io.println por io.debug, ya que esta función imprime un valor de cualquier tipo.

import gleam/io


pub fn main() {

  io.println("My lucky number is:")

  io.debug(4)

}


Gleam no tiene nulos, ni conversiones implícitas, ni excepciones, y siempre realiza una verificación de tipo completa. Si el código se compila, puede estar razonablemente seguro de que no tendrá inconsistencias que puedan causar errores o fallas.

lunes, 5 de agosto de 2024

Results de Gleam


import gleam/int

import gleam/io


pub fn main() {

  let _ = io.debug(buy_pastry(10))

  let _ = io.debug(buy_pastry(8))

  let _ = io.debug(buy_pastry(5))

  let _ = io.debug(buy_pastry(3))

}


pub type PurchaseError {

  NotEnoughMoney(required: Int)

  NotLuckyEnough

}


fn buy_pastry(money: Int) -> Result(Int, PurchaseError) {

  case money >= 5 {

    True ->

      case int.random(4) == 0 {

        True -> Error(NotLuckyEnough)

        False -> Ok(money - 5)

      }

    False -> Error(NotEnoughMoney(required: 5))

  }

}


Gleam no utiliza excepciones, sino que los cálculos que pueden tener éxito o fallar devuelven un valor del tipo Result(value, error). Tiene dos variantes:

  • Ok, que contiene el valor de retorno de un cálculo exitoso.
  • Error, que contiene el motivo de un cálculo fallido.

El tipo es genérico con dos parámetros de tipo, uno para el valor de éxito y otro para el error. Con estos, el resultado puede contener cualquier tipo de éxito o fracaso.

Comúnmente, un programa o biblioteca de Gleam definirá un tipo personalizado con una variante para cada posible problema que pueda surgir, junto con cualquier información de error que pueda ser útil para el programador.

Esto es ventajoso sobre las excepciones, ya que puede ver inmediatamente qué errores puede devolver una función, si los hay, y el compilador se asegurará de que se gestionen. ¡No hay sorpresas desagradables con excepciones inesperadas!

Un valor de resultado se puede gestionar mediante la coincidencia de patrones con una expresión de case, pero dada la frecuencia con la que se devuelven los resultados, esto puede volverse difícil de manejar. El código Gleam comúnmente utiliza el módulo de biblioteca estándar gleam/result y utiliza expresiones cuando trabaja con resultados.


domingo, 25 de agosto de 2024

Módulo List de Gleam


import gleam/io

import gleam/list


pub fn main() {

  let ints = [0, 1, 2, 3, 4, 5]


  io.println("=== map ===")

  io.debug(list.map(ints, fn(x) { x * 2 }))


  io.println("=== filter ===")

  io.debug(list.filter(ints, fn(x) { x % 2 == 0 }))


  io.println("=== fold ===")

  io.debug(list.fold(ints, 0, fn(count, e) { count + e }))


  io.println("=== find ===")

  let _ = io.debug(list.find(ints, fn(x) { x > 3 }))

  io.debug(list.find(ints, fn(x) { x > 13 }))

}

=== map ===
[0, 2, 4, 6, 8, 10]
=== filter ===
[0, 2, 4]
=== fold ===
15
=== find ===
Ok(4)
Error(Nil)

El módulo de la biblioteca estándar gleam/list contiene funciones para trabajar con listas. Es probable que un programa Gleam haga un uso intensivo de este módulo, ya que las distintas funciones sirven como diferentes tipos de bucles sobre listas.

  • map crea una nueva lista ejecutando una función en cada elemento de la lista.
  • filter crea una nueva lista que contiene solo los elementos para los que una función devuelve verdadero.
  • fold combina todos los elementos de una lista en un único valor ejecutando una función de izquierda a derecha en cada elemento, pasando el resultado de la llamada anterior a la siguiente llamada.
  • find devuelve el primer elemento de una lista para el que una función devuelve verdadero.

Vale la pena familiarizarse con todas las funciones de este módulo al escribir código Gleam, ¡las usará mucho!

viernes, 6 de septiembre de 2024

Módulo de opciones



import gleam/io

import gleam/option.{type Option, None, Some}


pub type Person {

  Person(name: String, pet: Option(String))

}


pub fn main() {

  let person_with_pet = Person("Al", Some("Nubi"))

  let person_without_pet = Person("Maria", None)


  io.debug(person_with_pet)

  io.debug(person_without_pet)

}


Person(name: "Al", pet: Some("Nubi"))
Person(name: "Maria", pet: None)


Los valores en Gleam no son nulos, por lo que el módulo de la biblioteca estándar gleam/option define el tipo Option de Gleam, que se puede utilizar para representar un valor que está presente o ausente.

El tipo option es muy similar al tipo result, pero no tiene un valor de error. Algunos lenguajes tienen funciones que devuelven una opción cuando no hay detalles de error adicionales que proporcionar, pero Gleam siempre utiliza result. Esto hace que todas las funciones falibles sean consistentes y elimina cualquier código repetitivo que se requeriría al mezclar funciones que utilizan cada tipo.

lunes, 26 de febrero de 2024

Hello world en Gleam

 


// Import a Gleam module from the standard library

import gleam/io


pub fn main() {

  // Print to the console

  io.println("Hello world!")

}


Aquí hay un programa que imprime el texto "Hello world!".

Para ello, utiliza la función println que se ha importado del módulo gleam/io, que forma parte de la biblioteca estándar de Gleam.

Para ejecutar este programa se usa el comando gleam run.


lunes, 4 de marzo de 2024

El tipo Float de Gleam

 


import gleam/io

import gleam/float


pub fn main() {

  // Float arithmetic

  io.debug(1.0 +. 1.5)

  io.debug(5.0 -. 1.5)

  io.debug(5.0 /. 2.5)

  io.debug(3.0 *. 3.5)


  // Float comparisons

  io.debug(2.2 >. 1.3)

  io.debug(2.2 <. 1.3)

  io.debug(2.2 >=. 1.3)

  io.debug(2.2 <=. 1.3)


  // Equality works for any type

  io.debug(1.1 == 1.1)

  io.debug(2.1 == 1.2)


  // Division by zero is not an error

  io.debug(3.14 /. 0.0)


  // Standard library float functions

  io.debug(float.max(2.0, 9.5))

  io.debug(float.ceiling(5.4))

}


El tipo Float de Gleam representa números que no son enteros.

Los operadores numéricos de Gleam no están sobrecargados, por lo que existen operadores dedicados para trabajar con flotantes.

Los flotantes se representan como números de punto flotante de 64 bits tanto en Erlang como de JavaScript. El comportamiento del punto flotante es nativo de sus respectivos runtimes, por lo que su comportamiento exacto será ligeramente diferente en los dos runtimes.

En JavaScript, exceder el valor máximo (o mínimo) representable para un valor de punto flotante dará como resultado Infinity (o -Infinity). Si intentas dividir dos infinitos, obtendrás NaN como resultado.

Cuando se ejecuta en BEAM, cualquier desbordamiento generará un error. Por lo tanto, no hay ningún valor flotante NaN o Infinity en el tiempo de ejecución de Erlang.

La división por cero no se desbordará, sino que se define como cero.

El módulo de biblioteca estándar gleam/float contiene funciones para trabajar con flotantes.


miércoles, 6 de marzo de 2024

Strings en Gleam



import gleam/io

import gleam/string


pub fn main() {

  // String literals

  io.debug("👩‍💻 こんにちは Gleam 🏳️‍🌈")

  io.debug(

    "multi

    line

    string",

  )

  io.debug("\u{1F600}")


  // Double quote can be escaped

  io.println("\"X\" marks the spot")


  // String concatenation

  io.debug("One " <> "Two")


  // String functions

  io.debug(string.reverse("1 2 3 4 5"))

  io.debug(string.append("abc", "def"))

}


En Gleam, las cadenas se escriben como texto entre comillas dobles, pueden abarcar varias líneas y contener caracteres Unicode.

El operador <> se puede utilizar para concatenar cadenas.

Se admiten varias secuencias de escape:

\" - comillas dobles
\\ - barra invertida
\f - avance de formulario
\n - nueva línea
\r - retorno de carro
\t - pestaña
\u{xxxxxx} - punto de código Unicode

El módulo de biblioteca estándar gleam/string contiene funciones para trabajar con cadenas.

domingo, 15 de septiembre de 2024

Use de Gleam


import gleam/io

import gleam/result


pub fn main() {

  let _ = io.debug(without_use())

  let _ = io.debug(with_use())

}


pub fn without_use() {

  result.try(get_username(), fn(username) {

    result.try(get_password(), fn(password) {

      result.map(log_in(username, password), fn(greeting) {

        greeting <> ", " <> username

      })

    })

  })

}


pub fn with_use() {

  use username <- result.try(get_username())

  use password <- result.try(get_password())

  use greeting <- result.map(log_in(username, password))

  greeting <> ", " <> username

}


// Here are some pretend functions for this example:


fn get_username() {

  Ok("alice")

}


fn get_password() {

  Ok("hunter2")

}


fn log_in(_username: String, _password: String) {

  Ok("Welcome")

}


El resultado es : 

Ok("Welcome, alice")
Ok("Welcome, alice")

Gleam carece de excepciones, macros, clases de tipos, retornos anticipados y una variedad de otras características, en lugar de eso, se centra en funciones de primera clase y coincidencia de patrones. Esto hace que el código de Gleam sea más fácil de entender, pero a veces puede resultar en una sangría excesiva.

La expresión use de Gleam ayuda en este caso al permitirnos escribir código que utiliza devoluciones de llamadas en un estilo sin sangría, como se muestra en el código anterior. 

La función de orden superior que se llama va del lado derecho del operador <-. Debe tomar una función de devolución de llamada como argumento final.

Los nombres de los argumentos para la función de devolución de llamada van del lado izquierdo del operador <-. La función puede tomar cualquier cantidad de argumentos, incluido cero.

Todo el código restante en el bloque {} que lo encierra se convierte en el cuerpo de la función de devolución de llamada.

Esta es una característica muy útil y capaz, pero la aplicación excesiva de use puede resultar en un código poco claro, especialmente para principiantes. ¡Por lo general, la sintaxis de llamada de función regular da como resultado un código más accesible!

viernes, 9 de agosto de 2024

Paquete de la biblioteca estándar de Gleam


import gleam/io


pub fn main() {

  io.println("Hello, Joe!")

  io.println("Hello, Mike!")

}


La biblioteca estándar de Gleam es un paquete de Gleam normal que se ha publicado en el repositorio de paquetes Hex. Puede optar por no utilizarla si lo desea, aunque casi todos los proyectos de Gleam dependen de ella.

Todos los módulos importados que usamos, como gleam/io , son de la biblioteca estándar.

Toda la documentación de la biblioteca estándar está disponible en HexDocs. 

domingo, 1 de septiembre de 2024

El Módulo Result de Gleam



import gleam/int

import gleam/io

import gleam/result


pub fn main() {

  io.println("=== map ===")

  let _ = io.debug(result.map(Ok(1), fn(x) { x * 2 }))

  let _ = io.debug(result.map(Error(1), fn(x) { x * 2 }))


  io.println("=== try ===")

  let _ = io.debug(result.try(Ok("1"), int.parse))

  let _ = io.debug(result.try(Ok("no"), int.parse))

  let _ = io.debug(result.try(Error(Nil), int.parse))


  io.println("=== unwrap ===")

  io.debug(result.unwrap(Ok("1234"), "default"))

  io.debug(result.unwrap(Error(Nil), "default"))


  io.println("=== pipeline ===")

  int.parse("-1234")

  |> result.map(int.absolute_value)

  |> result.try(int.remainder(_, 42))

  |> io.debug

}

=== map ===
Ok(2)
Error(1)
=== try ===
Ok(1)
Error(Nil)
Error(Nil)
=== unwrap ===
"1234"
"default"
=== pipeline ===
Ok(16)

El módulo de la biblioteca estándar gleam/result contiene funciones para trabajar con resultados. Los programas Gleam harán un uso intensivo de este módulo para evitar expresiones de caso anidadas excesivas al llamar a múltiples funciones que pueden fallar.

  • map actualiza un valor contenido dentro de Ok de un resultado llamando a una función dada sobre él. Si el resultado es un error, no se llama a la función.
  • try ejecuta una función que devuelve un resultado sobre el valor contenido dentro de Ok de un resultado. Si el resultado es un error, no se llama a la función. Esto es útil para encadenar varias llamadas de función que pueden fallar, una tras otra, deteniéndose en el primer error.
  • unwrap extrae el valor de éxito de un resultado o devuelve un valor predeterminado si el resultado es un error.

Las funciones de resultado se utilizan a menudo con canalizaciones para encadenar varias llamadas a funciones que devuelven resultados.

sábado, 2 de marzo de 2024

El tipo Int de Gleam


import gleam/io

import gleam/int


pub fn main() {

  // Int arithmetic

  io.debug(1 + 1)

  io.debug(5 - 1)

  io.debug(5 / 2)

  io.debug(3 * 3)

  io.debug(5 % 2)


  // Int comparisons

  io.debug(2 > 1)

  io.debug(2 < 1)

  io.debug(2 >= 1)

  io.debug(2 <= 1)


  // Equality works for any type

  io.debug(1 == 1)

  io.debug(2 == 1)


  // Standard library int functions

  io.debug(int.max(42, 77))

  io.debug(int.clamp(5, 10, 20))

}

El tipo Int de Gleam representa números enteros.

Existen operadores aritméticos y de comparación para enteros, así como el operador de igualdad que funciona en todos los tipos.

Cuando se ejecuta en la máquina virtual Erlang, los ints no tienen un tamaño máximo ni mínimo. Cuando se ejecuta en JavaScript, los ints se representan utilizando números de punto flotante de 64 bits de JavaScript,

El módulo de biblioteca estándar gleam/int contiene funciones para trabajar con ints.

domingo, 28 de abril de 2024

Pipelines en Gleam


 import gleam/io

import gleam/string


pub fn main() {

  // Without the pipe operator

  io.debug(string.drop_left(string.drop_right("Hello, Joe!", 1), 7))


  // With the pipe operator

  "Hello, Mike!"

  |> string.drop_right(1)

  |> string.drop_left(7)

  |> io.debug


  // Changing order with function capturing

  "1"

  |> string.append("2")

  |> string.append("3", _)

  |> io.debug

}

Es común querer llamar a una serie de funciones, pasando el resultado de una a la siguiente. Con la sintaxis de llamada a función normal, esto puede resultar un poco difícil de leer, ya que hay que leer el código de adentro hacia afuera.

El operador de tubería de Gleam |> ayuda con este problema permitiéndole escribir código de arriba a abajo. Es como el | en consolas unix. Es decir,  toma el resultado de la expresión de su izquierda y lo pasa como argumento a la función de su derecha.

Primero comprobará si el valor de la izquierda podría usarse como primer argumento de la llamada. Por ejemplo, a |> b(1, 2) se convertiría en b(a, 1, 2). De lo contrario, se recurre a llamar al resultado del lado derecho como una función, por ejemplo, b(1, 2)(a)

El código Gleam generalmente se escribe con el "asunto" de la función como primer argumento, para que sea más fácil de canalizar. Si desea canalizar a una posición diferente, puede utilizar una función de captura "_" para insertar el argumento en la posición deseada.

viernes, 6 de septiembre de 2024

Módulo Dict de Gleam

 


import gleam/dict

import gleam/io


pub fn main() {

  let scores = dict.from_list([#("Lucy", 13), #("Drew", 15)])

  io.debug(scores)


  let scores =

    scores

    |> dict.insert("Bushra", 16)

    |> dict.insert("Darius", 14)

    |> dict.delete("Drew")

  io.debug(scores)

}

El resultado : 

dict.from_list([#("Drew", 15), #("Lucy", 13)])
dict.from_list([#("Darius", 14), #("Bushra", 16), #("Lucy", 13)])


El módulo estándar gleam/dict define el tipo Dict de Gleam y las funciones para trabajar con él. Un dict es una colección de claves y valores que otros lenguajes pueden llamar un mapa hash o una tabla.

new y from_list se pueden utilizar para crear nuevos dicts.

insert y delete se utilizan para agregar y eliminar elementos de un dict.

Al igual que las listas, los dicts son inmutables. Insertar o eliminar un elemento de un dict devolverá un nuevo dict con el elemento agregado o eliminado.

Los dicts no están ordenados. Si parece que los elementos de un dict están en un orden determinado, es incidental y no se debe confiar en ello. Cualquier orden puede cambiar sin previo aviso en futuras versiones o en diferentes entornos de ejecución.

martes, 7 de mayo de 2024

Expresiones de casos en Gleam


import gleam/int

import gleam/io


pub fn main() {

  let x = int.random(5)

  io.debug(x)


  let result = case x {

    // Match specific values

    0 -> "Zero"

    1 -> "One"


    // Match any other value

    _ -> "Other"

  }

  io.debug(result)

}


La expresión de caso es el tipo más común de control de flujo en el código Gleam. Es similar al switch en otros lenguajes, pero más poderoso que la mayoría.

Permite al programador decir "si los datos tienen esta forma, entonces ejecute este código", un proceso llamado coincidencia de patrones.

Gleam realiza una verificación exhaustiva para garantizar que los patrones en una expresión de caso cubran todos los valores posibles. Con esto, puede tener la confianza de que su lógica está actualizada para el diseño de los datos con los que está trabajando.


sábado, 1 de junio de 2024

Recursión en Gleam



import gleam/io


pub fn main() {

  io.debug(factorial(5))

  io.debug(factorial(7))

}


// A recursive functions that calculates factorial

pub fn factorial(x: Int) -> Int {

  case x {

    // Base case

    0 -> 1

    1 -> 1


    // Recursive case

    _ -> x * factorial(x - 1)

  }

}


Gleam no tiene bucles, sino que la iteración se realiza mediante recursividad, es decir, mediante funciones de nivel superior que se llaman a sí mismas con diferentes argumentos.

Una función recursiva debe tener al menos un caso base y al menos un caso recursivo. Un caso base devuelve un valor sin volver a llamar a la función. Un caso recursivo vuelve a llamar a la función con diferentes entradas, volviendo a realizar un bucle.

La biblioteca estándar de Gleam tiene funciones para varios patrones de bucles comunes, algunos de los cuales se introducirán en lecciones posteriores; sin embargo, para bucles más complejos, la recursividad manual suele ser la forma más clara de escribirlo.

La recursividad puede parecer desalentadora o confusa al principio si estás más familiarizado con los lenguajes que tienen características especiales de bucle, ¡pero mantente firme! Con el tiempo, resultará tan familiar y cómodo como cualquier otra forma de iteración.

miércoles, 6 de marzo de 2024

Bools en Gleam



import gleam/io

import gleam/bool


pub fn main() {

  // Bool operators

  io.debug(True && False)

  io.debug(True && True)

  io.debug(False || False)

  io.debug(False || True)


  // Bool functions

  io.debug(bool.to_string(True))

  io.debug(bool.to_int(False))

}


Un Bool es Verdadero o Falso.

El ||, &&, y ! Los operadores se pueden utilizar para manipular bools.

El || y los operadores && están en cortocircuito, lo que significa que si el lado izquierdo del operador es Verdadero para || o False para && entonces no se evaluará el lado derecho del operador.

El módulo de biblioteca estándar gleam/bool contiene funciones para trabajar con bools.

sábado, 24 de febrero de 2024

Gleam Language Tour


Como tengo tanto tiempo y siempre viene bien aprender un nuevo lenguaje, voy a hacer el Gleam Language Tour. 

Ya he hablado de Gleam en otro post y no me quiero repetir. Les comparto el link y los invito a hacerlo conmigo. 

Dejo link: https://tour.gleam.run/basics/hello-world/

lunes, 29 de julio de 2024

Nil de Gleam


import gleam/io


pub fn main() {

  let x = Nil

  io.debug(x)

  let result = io.println("Hello!")

  io.debug(result == Nil)

}


Nil es el tipo de unidad de Gleam. Es un valor que devuelven las funciones que no tienen nada más que devolver, ya que todas las funciones deben devolver algo.

Nil no es un valor válido de ningún otro tipo. Por lo tanto, los valores en Gleam no son nulos. Si el tipo de un valor es Nil, entonces es el valor Nil. Si es otro tipo, entonces el valor no es Nil.