Necesitamos hablar de los paréntesis (2020)

Las discusiones sobre cuánto deben depender los lenguajes de programación de los paréntesis y la precedencia de operadores revelan compensaciones profundas entre legibilidad, familiaridad y poder de metaprogramación. Algunos participantes abogan por una precedencia mínima y una agrupación más explícita (o incluso sintaxis estilo RPN), mientras que otros defienden las reglas convencionales similares a las matemáticas y los S‑expresiones totalmente parentetizados de Lisp, especialmente cuando se combinan con buena indentación y soporte del editor. El intercambio también aborda cómo la sintaxis moldea las herramientas, el alcance y la facilidad de transformar el código, y por qué, a pesar de las ventajas de las macros y del enfoque de “código como datos” de Lisp, la mayoría de los lenguajes convencionales siguen favoreciendo formas sintácticas más variadas y menos uniformes.

Precedencia de operadores frente a paréntesis obligatorios

  • Un grupo sostiene que la precedencia de operadores es un error de diseño; las expresiones con varios operadores, como 1 + 1 * 2 o a | b || c >> d & e * f, deberían ser errores de sintaxis salvo que se parenteticen explícitamente.
  • Otros discrepan firmemente, citando la simplicidad de la notación, los paralelismos con el álgebra y la carga de un código excesivamente parentetizado.
  • Compromiso propuesto: un orden de precedencia parcial. Se permiten combinaciones comunes (por ejemplo, * por encima de +); las mezclas poco habituales (por ejemplo, * con &) se rechazan como “precedencia ambigua”.
  • El debate se extiende a las matemáticas: algunos dicen que la precedencia es inherente (“orden de operaciones”); otros insisten en que es puramente una propiedad de la notación, a menudo expresada visualmente mediante fracciones, superíndices, radicales, etc.

Paréntesis en Lisp, legibilidad y herramientas

  • Muchos señalan que en Lisp, la indentación automática, la edición estructural y el resaltado de paréntesis se consideran esenciales; estas herramientas revelan rápidamente paréntesis faltantes o mal colocados.
  • Algunos sostienen que el único tipo de paréntesis de Lisp perjudica la legibilidad y sugieren varios tipos de corchetes para distintos roles sintácticos, o incluso corchetes intercambiables solo para agrupación visual.
  • Contrapunto: los usuarios experimentados de Lisp en su mayoría “ven formas”, no paréntesis, y se apoyan en patrones que comienzan con símbolos en lugar de contar corchetes.
  • Se elogia la edición estructural: los delimitadores explícitos más el autoformateo actúan como una especie de “contabilidad por partida doble” de la estructura del código.

Estilo sintáctico, espacios en blanco y alcance

  • Algunos celebran los lenguajes que eliminan paréntesis innecesarios en construcciones como condiciones if (Go, Scala 3).
  • Hay desacuerdo sobre el espacio en blanco significativo: algunos prefieren delimitadores explícitos; otros encuentran más legible una sintaxis centrada en la indentación.
  • Discusión sobre el alcance: los bloques léxicos ajustados ({} o formas let) pueden reducir las variables vivas, pero no todas las vidas útiles pueden minimizarse; ejemplos en C, Rust (vidas útiles no léxicas) y código funcional/monádico ilustran los compromisos.

Código como datos y metaprogramación en Lisp

  • Varios comentarios subrayan que los paréntesis de Lisp representan listas; los programas son listas, y citar convierte código en datos.
  • Operaciones simples sobre listas pueden transformar el código (por ejemplo, reemplazar todos los * por + y luego eval), lo que sustenta macros potentes y sintaxis específicas de dominio.
  • Los entusiastas ven esto como la principal fortaleza de Lisp; los escépticos responden que otros lenguajes ahora ofrecen metaprogramación potente con una sintaxis visualmente menos repetitiva, y cuestionan si los paréntesis son un buen intercambio ergonómico.