Programación funcional en Go: técnicas avanzadas y ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Programación funcional en Go: técnicas avanzadas y ejemplos



Go (Golang) no fue diseñado originalmente como un lenguaje puramente funcional, sin embargo, sus potentes capacidades, como los closures, las funciones de primera clase y las gorutinas, permiten aplicar con éxito el paradigma de la programación funcional (PF) a un nivel avanzado. Este artículo está destinado a desarrolladores que ya están familiarizados con los conceptos básicos de Go y desean profundizar en técnicas funcionales para escribir código más predecible, comprobable y concurrente. Exploraremos el currying, la composición de funciones, el trabajo con estructuras similares a mónadas y la integración de PF con gorutinas.



1. Currying y aplicación parcial de funciones



El currying es la transformación de una función que toma varios argumentos en una secuencia de funciones, cada una de las cuales toma un solo argumento. En Go, donde no hay soporte incorporado para currying, lo implementamos a través de closures.



Ejemplo: currying para un logger configurable



package main

import "fmt"

// Función curryficada: prefijo -> mensaje -> salidafunc createLogger(prefix string) func(string) { return func(message string) { fmt.Printf("[%s] %s", prefix, message) }}

func main() { infoLogger := createLogger("INFO") errorLogger := createLogger("ERROR")

infoLogger("Sistema iniciado") errorLogger("Error de conexión") // Salida: // [INFO] Sistema iniciado // [ERROR] Error de conexión}


La aplicación parcial es un caso especial de currying, cuando fijamos una parte de los argumentos. En Go, esto es especialmente útil para crear versiones especializadas de funciones.



// Aplicación parcial: fijamos el coeficientefunc multiply(a, b int) int {    return a * b}

func partialMultiply(a int) func(int) int { return func(b int) int { return multiply(a, b) }}

func main() { double := partialMultiply(2) triple := partialMultiply(3)

fmt.Println(double(5)) // 10 fmt.Println(triple(5)) // 15}


2. Composición de funciones y pipelines



La composición es la combinación de funciones simples en otras más complejas. En Go, podemos construir cadenas de transformaciones, pasando el resultado de una función como entrada a otra. Esto funciona de manera especialmente potente en combinación con interfaces y genéricos (Go 1.18+).



Ejemplo: composición para procesamiento de cadenas



package main

import ( "fmt" "strings" "unicode")

type StringTransform func(string) string

// Compose crea la composición de dos funcionesfunc Compose(f, g StringTransform) StringTransform { return func(s string) string { return f(g(s)) }}

// Pipeline combina varias funcionesfunc Pipeline(transforms ...StringTransform) StringTransform { return func(s string) string { for _, t := range transforms { s = t(s) } return s }}

func removeSpaces(s string) string { return strings.ReplaceAll(s, " ", "")}

func toUpper(s string) string { return strings.ToUpper(s)}

func removeDigits(s string) string { var result strings.Builder for _, r := range s { if !unicode.IsDigit(r) { result.WriteRune(r) } } return result.String()}

func main() { // Composición de dos funciones cleanAndUpper := Compose(removeSpaces, toUpper) result1 := cleanAndUpper("go 1.18 rocks") fmt.Println(result1) // "GO1.18ROCKS"

// Pipeline de tres funciones pipeline := Pipeline(removeSpaces, removeDigits, toUpper) result2 := pipeline("go 1.18 rocks") fmt.Println(result2) // "GOROCKS"}


Este enfoque permite construir transformaciones complejas a partir de bloques simples y comprobables. Cada función del pipeline puede ser probada por separado.



3. Estructuras similares a mónadas: traba

Blogs

Book Recommendations