19 puntos por GN⁺ 2024-09-13 | 3 comentarios | Compartir por WhatsApp
  • "Poco práctico", "académico", "de nicho"

    • Son las reacciones que muestra la gente cuando se entera de que mi lenguaje de programación favorito es Haskell
    • Lo uso no solo para proyectos de hobby, sino también para construir servidores web reales
    • En Converge lidero equipos que trabajan con Haskell
  • Malentendidos sobre Haskell

    • Los problemas que puede resolver un lenguaje de programación de propósito general también pueden resolverse en otros lenguajes
    • Muchas funciones que se incorporan en Python, Rust, Typescript y otros se inspiraron en Haskell o están implementadas de forma más sólida en Haskell
    • Parece una variación de la ideología de "elige tecnología aburrida"
    • Existe la idea equivocada de que programar no es matemáticas y que hay que excluir los elementos matemáticos
  • Objetivo de este artículo

    • Busca explicar de forma lógica por qué Haskell es la mejor opción para la mayoría de los programadores
    • Es especialmente útil para quienes quieren escribir software sólido de manera productiva
    • También enfatiza el lado divertido de escribir software
  • Desaprender y reaprender

    • La mayoría de los programadores están acostumbrados al paradigma imperativo
    • Haskell es un lenguaje puramente funcional, por lo que su curva de aprendizaje es pronunciada
    • El propio lenguaje Haskell es fácil de aprender si se limita a un subconjunto simple
    • La programación funcional exige un cambio completo en la manera de estructurar programas
    • Este proceso ayuda a crecer como programador
    • Cita de Alan Perlis:

      Un lenguaje que no afecta tu forma de pensar sobre programación no vale la pena conocer.

Breve explicación de la sintaxis

  • :: indica una firma de tipo (ej.: myThing :: String)

  • Las llamadas a funciones no usan paréntesis; los argumentos se listan después del nombre de la función separados por espacios (ej.: doSomething withThis withThat)

  • En una firma de tipo, las minúsculas son variables de tipo y representan cualquier tipo (ej.: head :: [a] -> a)

  • Hay dos tipos de flechas, -> y =>:

    • -> describe el tipo de una función (ej.: add1 :: Int -> Int)
    • => describe restricciones sobre variables de tipo y siempre va primero (ej.: add1 :: Num a => a -> a)
  • Los comentarios comienzan con --

  • return es una función común, no tiene el significado que uno esperaría

  • do es azúcar sintáctica para que se vea como estilo imperativo

  • Hay varias formas de asignar valores a variables locales:

    let x = <something> in  
    <expression>  
    

    o x <- <something>

  • Reducir errores

    • En muchos lenguajes se escriben muchos casos de prueba para que el código quede "correcto"
    • Haskell reduce enormemente esa carga con su sistema de tipos y la programación puramente funcional
    • El potente sistema de tipos de Haskell ofrece garantías concretas sobre el programa y las aplica rigurosamente
    • Características del sistema de tipos:
      • No hay tipos anulables
      • Se pueden expresar cálculos que pueden fallar
      • Pattern matching y verificación de exhaustividad
      • Evita gratis la obsesión por los primitivos
  • Ventajas de no tener valores nulos

    • Como no existe el valor null, siempre se sabe si un valor corresponde al tipo esperado
    • Esto evita errores en tiempo de ejecución y reduce la superficie de error
  • Expresión de cálculos que pueden fallar

    • Con los tipos Maybe y Either se expresan explícitamente los cálculos que pueden fallar
    • Maybe representa un cálculo que puede o no producir un resultado
      safeHead :: [a] -> Maybe a  
      
    • Either puede tener dos valores (Left a o Right b)
      validateAddress :: String -> Either AddressParseError ValidAddress  
      
  • Pattern matching y verificación de exhaustividad

    • Hay que manejar todo el dominio de entrada; de lo contrario, el compilador genera un error
    • Esto previene errores en tiempo de ejecución y aumenta la confiabilidad del programa
  • Evitar la obsesión por los primitivos

    • Con newtype se pueden crear fácilmente tipos semánticamente más significativos
    newtype VenueName = VenueName String  
    newtype EventName = EventName String  
    
  • Ventajas de la programación puramente funcional

    • Los datos son inmutables, así que no hace falta preocuparse por mutaciones de estado
    • Los efectos secundarios se manejan de forma explícita, y las funciones dependen solo de sus entradas sin efectos secundarios
    • Esto aumenta la previsibilidad y estabilidad del programa
  • Manejo explícito de efectos secundarios

    • Con la mónada IO, los efectos secundarios se separan y controlan dentro del código
    • La firma de tipo de una función permite saber que produce efectos secundarios
    sendGreetings :: User -> IO Response  
    
  • Mónadas y control de efectos

    • Con typeclasses y mónadas se codifican con precisión los efectos que una función puede ejecutar
    • Esto evita efectos secundarios no intencionales y mejora la estabilidad del código
  • Factores que mejoran la productividad

    • El potente sistema de tipos y la naturaleza puramente funcional facilitan la reutilización de código y la generalización de conceptos
    • Conceptos como Functor y Monoid permiten aplicar el mismo patrón a distintas estructuras de datos
    fmap (+2) [1, 2, 3] -- [3, 4, 5]  
    fmap (+2) (Just 2) -- Just 4  
    
  • Refactorización sin miedo

    • Gracias a la rigurosidad del compilador, al cambiar el código hay menos riesgo de introducir bugs nuevos
    • El sistema de tipos permite expresar con precisión el dominio del programa, así que se puede modificar el código con confianza
  • Mejor comprensión del programa

    • La programación declarativa permite expresar con precisión el dominio del problema
    • Facilita entender el significado del programa y aumenta su confiabilidad
    • Al eliminar complejidad innecesaria, se puede razonar sobre el programa de forma más sólida
  • Tipos de datos algebraicos y typeclasses

    • Permiten construir lenguajes específicos de dominio dentro de Haskell
    • Esto ayuda a entender y mantener el programa
  • Programa de ejemplo

    • Se escribe una herramienta contable simple para aplicar de forma práctica los conceptos de Haskell

Epílogo

  • Usar Haskell es disfrutable y productivo
  • La combinación de un sistema de tipos potente y expresivo con programación puramente funcional hace especial a Haskell
  • Otros lenguajes también están incorporando estas funciones, pero en Haskell estas características están en su base
  • Aprender Haskell cambiará tu forma de pensar sobre la programación

Opinión de GN⁺

  • El valor de aprender Haskell

    • Ayuda a ampliar la forma de pensar como programador
    • Entender el paradigma funcional permite escribir mejor código incluso en otros lenguajes
  • El auge de la programación funcional

    • Tiene fortalezas en procesamiento paralelo y concurrencia, por lo que encaja bien en entornos modernos de cómputo
    • El control de efectos secundarios permite escribir código predecible
  • Comparación con otros lenguajes

    • Hay lenguajes como Rust o Scala que también soportan programación funcional, pero la pureza y el sistema de tipos de Haskell son únicos
    • Los conceptos de Haskell pueden ser útiles al aprender nuevos lenguajes
  • Aplicabilidad en el trabajo real

    • La curva de aprendizaje inicial es empinada, pero la productividad mejora en proporción al tiempo invertido
    • Es útil en sistemas complejos o dominios sensibles a errores
  • Comunidad y ecosistema

    • La comunidad de Haskell es activa, y se siguen desarrollando diversas bibliotecas y herramientas
    • Participar en proyectos de código abierto puede ayudar a mejorar las habilidades

3 comentarios

 
cosine20 2024-09-19

Comencé con F#, al que se le añadió practicidad.

 
savvykang 2024-09-13

Los ADT y el pattern matching están bien, pero por favor dejen de hablar tanto de mónadas y funtores.

 
GN⁺ 2024-09-13
Opiniones en Hacker News
  • Haskell obliga a escribir funciones totales en lugar de funciones parciales

    • Haskell no evita la recursión infinita
    • En el ecosistema de FP que avanza hacia tipos dependientes, es importante evitar que el verificador de tipos se ejecute indefinidamente
    • Muchas de las extensiones temporales de Haskell causan problemas
    • Si te gusta la filosofía de Haskell, no deberías limitarte solo a Haskell
    • La estandarización de Haskell fracasó
    • La propuesta de valor única de GHC podría ser su sistema de ejecución
  • He usado Haskell durante 10 años y las herramientas han mejorado mucho

    • ghcup, el aislamiento de cabal y HLS son estables
    • No he encontrado muchas carencias en el ecosistema de bibliotecas
    • El tiempo de compilación de Haskell sigue siendo incómodo
    • El tiempo de compilación de dependencias se vuelve largo
  • El sistema de tipos de Haskell no demuestra que las funciones sean totales

    • En la programación general, demostrar la totalidad no es útil
    • La mayoría de la gente verifica si un programa realmente funciona mediante pruebas
  • El lenguaje Haskell es bueno, pero el ecosistema todavía tiene mucho camino por recorrer

    • El compilador es lento
    • Tiene poca capacidad para reportar errores
    • El primer error detiene el resto de la compilación
    • Las herramientas siguen siendo insuficientes en comparación con otros lenguajes funcionales
    • El ecosistema de bibliotecas es limitado
    • Las ideas de Haskell han influido en muchos otros lenguajes
  • Quiero usar Haskell u otro lenguaje funcional de manera profesional

    • Lenguajes como Go fueron fáciles de aprender
    • Quiero aprender a construir una base de código en lenguajes funcionales
  • Haskell tuvo un gran impacto en la forma de pensar la programación y en la arquitectura del código

    • El sistema de tipos de Haskell es muy poderoso y fácil de entender
    • Fue divertido microoptimizar código en Haskell
    • Las herramientas siguen siendo insuficientes
  • Haskell experimenta con la evaluación perezosa a nivel de lenguaje

    • La evaluación perezosa se puede obtener a nivel de biblioteca estándar
  • La pureza extrema y la inmutabilidad de Haskell son un problema

    • A muchos programadores les resulta más fácil expresar bucles procedimentales/mutables
    • Rust usa un sistema de tipos competente y muchos modismos funcionales, pero permite usar bucles y mutabilidad
  • Haskell es muy adecuado para software de lógica de negocio (BLOBS)

    • La mayor parte de la lógica de negocio puede modelarse con tipos simples y pattern matching
    • Si mantienes simples las partes sencillas, se puede enseñar fácilmente incluso a colaboradores no técnicos
    • Haskell es divertido