¿Por qué un lenguaje debería preferir la sangría sobre los marcadores explícitos para bloques?

11

Estoy aprendiendo Haskell, y estaba buscando una herramienta de sangría automática. No parecía mucho, y aprendí que en Haskell (como en Python), la sangría significa un bloqueo. Como resultado, supongo que es imposible crear una herramienta de formateo automático, tan fuerte como en otros lenguajes de la familia C, que use marcadores explícitos, como {} (llaves) o begin endpalabras clave.

No me importa un lenguaje que imponga sangría para facilitar la lectura, pero no puedo entender los beneficios tanto de imponer sangría como de tener algún marcador explícito, de modo que las herramientas automatizadas puedan comprender qué pertenece en cada bloque.

Si la preferencia de la sangría que marca un bloque es para que el código se vea mejor, entonces todavía no entiendo la ventaja. Dado que las pestañas y los espacios se representan de manera diferente en diferentes editores y diferentes fuentes (las fuentes monoespaciales, por ejemplo, se ven más ordenadas), no es factible esperar que el programador presente el código decentemente. Una herramienta que pueda tener en cuenta el editor de texto actual sería mucho más apropiado para formatear el código correctamente.

¿Por qué un diseñador de lenguaje elegiría la sangría sobre los marcadores de bloque explícitos?

Reinstalar a Mónica
fuente
8
No es una respuesta, pero Haskell hace que la sensibilidad de los espacios en blanco sea mucho más opcional que python. Puede usar punto y coma para la mayoría de las cosas, y envolver bloques en llaves si lo desea. let x =1; y = 2; z = 3es completamente válido, como es do { putStrLn $ show x; putStrLn $ show y; putStrLn $ show z; }. Esos no necesitan estar en la misma línea.
KChaloux
8
"es imposible crear una herramienta de formateo automático" - en realidad, no hay necesidad de tal herramienta de formateo automático en Python debido a las reglas de sangría.
Doc Brown
13
Um, aumentar la sangría es un marcador de bloque explícito.
Karl Bielefeldt
3
@ K.Gkinis: La mejor fuente para las motivaciones exactas detrás de una decisión de diseño del lenguaje son los propios diseñadores del lenguaje.
Robert Harvey
3
Esta pregunta no es realmente subjetiva. Pregunta por qué algunos diseñadores de idiomas eligieron una determinada sintaxis. Esto puede ser respondido. Si la pregunta hubiera preguntado qué sintaxis es mejor , sería subjetiva.
JacquesB

Respuestas:

13

Guido Von Rossum

De una entrevista con Guido Van Rossum , que se puede ver en texto completo con books.google.com (el énfasis es mío):

La elección de la sangría para la agrupación no era un concepto novedoso en Python; Heredé esto de ABC , pero también ocurrió en occam, un idioma antiguo. No sé si los autores de ABC tuvieron la idea de occam, o si la inventaron de forma independiente, o si hubo un antepasado común. Por supuesto, podría haber optado por no seguir el ejemplo de ABC, como lo hice en otras áreas (por ejemplo, ABC usó mayúsculas para palabras clave de lenguaje y nombres de procedimientos, una idea que no copié), pero me gustó bastante la función mientras usaba ABC, ya que parecía eliminar un cierto tipo de debate inútil común entre los usuarios de C en ese momento, sobre dónde colocar las llaves .

Von Rossum se inspiró fuertemente en ABC , y aunque no tuvo que copiarlo todo, se mantuvo el uso de la sangría porque podría ser beneficioso para evitar guerras religiosas.

También sabía que el código legible usa la sangría voluntariamente de todos modos para indicar la agrupación, y me encontré con sutiles errores en el código donde la sangría no estaba de acuerdo con la agrupación sintáctica utilizando llaves, el programador y los revisores asumieron que la sangría coincidía con la agrupación y por lo tanto no noté el error. Una vez más, una larga sesión de depuración enseñó una valiosa lección.

Rossum también fue testigo de errores debido a la inconsistencia entre la agrupación y la sangría, y aparentemente aunque confiar en la sangría solo para estructurar el código sería más seguro contra los errores de programación 1 .

Donald E. Knuth y Peter J. Landin

En la entrevista a la que se hace referencia, Guido menciona la idea de Don Knuth de usar sangría. Esto se detalla en La cita de sangría de Knuth redescubierta , que cita la Programación estructurada con declaraciones Goto . Knuth también hace referencia a Los siguientes 700 lenguajes de programación de Peter John Landin (consulte la sección Discusión sobre sangría). Landin diseñó ISWIM que parece el primer idioma con sangría en lugar de bloques de inicio / finalización. Esos documentos tratan más sobre la viabilidad de usar sangría para estructurar programas en lugar de argumentos reales a favor de hacerlo.


1. Creo que este es, de hecho, un argumento a favor de tener construcciones de agrupación y formateo automático, para detectar y recuperarse de los errores de programación, que seguramente sucederán. Si arruinas tu sangría en Python, la persona que depura tu código tendrá que adivinar cuál es la correcta:

if (test(x)):
  foo(x)
  bar(x)

¿ barSiempre se llamará o solo si la prueba tiene éxito?

Las construcciones de agrupamiento agregan un nivel de redundancia que lo ayuda a detectar un error cuando sangra automáticamente su código. En C, el código equivalente se puede sangrar automáticamente de la siguiente manera:

if (test(x))
  foo(x);
bar(x);

Si tenía la intención de barestar al mismo nivel que foo, la sangría automática basada en la estructura del código me permite ver que hay algo mal que se puede solucionar agregando llaves alrededor fooy bar.

En Python: Mitos sobre la sangría , hay un ejemplo supuestamente malo de C:

/*  Warning:  bogus C code!  */

if (some condition)
        if (another condition)
                do_something(fancy);
else
        this_sucks(badluck);

Ese es el mismo caso que el anterior, en Emacs, resalto todo el bloque / función, presiono Tab y luego todo el código se reinventa. La discrepancia entre la sangría humana y la estructura del código me dice que algo está mal (¡eso y el comentario anterior!).

Además, el código intermedio donde la sangría está desactivada en C simplemente no pasa a través de la rama maestra, todas las comprobaciones de estilo en su lugar harían que GCC / Jenkins me gritaran. Recientemente tuve un problema similar al descrito anteriormente en Python, con una declaración desactivada por un nivel de sangría. A veces tengo un código en C que va más allá de una llave de cierre, pero luego presiono Tab y el código sangra "incorrectamente": esa es una oportunidad más para ver el error.

volcado de memoria
fuente
3
"Para evitar guerras religiosas ..." Me sorprende que la verdadera razón sea tan trivial.
Robert Harvey
1
@RobertHarvey: El énfasis en esa frase es por coredump, no por van Rossum. No es la razón principal si lees la cita de van Rossum en contexto.
JacquesB
@JacquesB Por favor, dime qué contexto falta en la cita, para que pueda editar la respuesta.
coredump
44
Sin embargo, no recibo tu comentario personal: si arruinas la sangría en Python, entonces tienes un error. Si atornillas llaves en C, tienes un error. Si utiliza la sangría automática, es exactamente lo mismo en ambos idiomas. Y si no usa la sangría automática, el error puede ocultarse furtivamente en C de una manera que no es posible en Python.
JacquesB
2
@JacquesB porque escribir una llave de cierre es algo que haces activamente; no sangrar lo suficiente es algo que puedes olvidar hacer. Por supuesto, puede olvidarse de cerrar un aparato ortopédico en el momento adecuado, pero eventualmente tendrá que hacerlo y tendrá otra oportunidad de pensarlo. Supongo que Python funciona bien para principiantes porque fuerza la atención a la sangría.
marstato
7

Esto es altamente subjetivo y la causa de muchas guerras de fuego. Sin embargo:

Tener símbolos que delimiten bloques y sangría viola el principio DRY , ya que expresa la misma información de dos maneras diferentes. La existencia de herramientas de sangría automatizadas es un síntoma de esta infracción DRY: el hecho de que pueda generar automáticamente la sangría muestra que es información redundante, y significa que la sangría y los símbolos pueden estar fuera de sincronización, lo que conduce a un código engañoso.

Las preguntas frecuentes sobre diseño e historia de Python establecen esto muy claramente:

¿Por qué Python usa sangría para agrupar declaraciones?

Guido van Rossum cree que el uso de sangría para la agrupación es extremadamente elegante y contribuye mucho a la claridad del programa promedio de Python. La mayoría de las personas aprenden a amar esta característica después de un tiempo.

Como no hay paréntesis de inicio / fin, no puede haber un desacuerdo entre la agrupación percibida por el analizador y el lector humano.

Es cierto que no puede crear una herramienta de sangría automática para Python, pero esto es algo bueno: significa que no tiene redundancias en la sintaxis que necesita herramientas automatizadas para conciliar.

Las pestañas vs espacios es una preocupación legítima en Python, y se recomienda nunca mezclar pestañas y espacios (para sangría) en la misma base de código.

Python heredó la sangría significativa del lenguaje predecesor (ahora obsoleto) ABC. ABC es uno de los pocos lenguajes de programación que ha utilizado pruebas de usabilidad para dirigir el diseño. Entonces, aunque las discusiones sobre la sintaxis generalmente se reducen a opiniones subjetivas y preferencias personales, la elección de una sangría significativa en realidad tiene una base más sólida.

JacquesB
fuente
66
La contabilidad de doble entrada también viola DRY. La redundancia es a veces una característica.
coredump
3
@coredump: Cierto, pero es una redundancia diseñada deliberadamente. La mayoría de los lenguajes de programación, incluido Python, contienen redundancias elegidas deliberadamente, por ejemplo, la passpalabra clave que se puede inferir automáticamente, pero que requiere que sea explícita ayuda a descubrir errores. La redundancia accidental de tener símbolos de inicio / fin (para el compilador) y sangría (para el lector humano) parece causar más errores de los que detecta. Al menos esta parece ser la opinión de van Rossum.
JacquesB
@coredump - Ahora sé por qué no soy contador.
JeffO
3
@coredump ¿También extrañas COBOL PROCEDURE DIVISION.? Nunca puedo decir dónde DATA DIVISIONcomienzan los fines y los procedimientos en estos nuevos idiomas.
msw
2
@coredump: "ver sangría contradice lo que tenía en mente es suficiente para evitar errores" - exactamente.
JacquesB
2

Los diseñadores de idiomas eligen espacios en blanco sintácticamente significativos porque creen (o al menos piensan que creen sus usuarios potenciales) que los puntos y comas agregan ruido al leer el código, lo que perjudica la productividad. Otra razón común es que el estilo de codificación malo / inconsistente perjudica la legibilidad: al forzar un esquema de sangría común, el lenguaje tiene una mejor legibilidad en general. Esa razón posterior es menos importante ahora que los IDE con formato automático son más comunes, pero aún pueden aplicarse.

Telastyn
fuente
1
Puedo ver por qué uno consideraría el punto y coma y el ruido de las llaves. Pero, ¿no es menos productivo tener que escribir 4/8/12 veces el espacio? Y si te pierdes uno (ya que son invisibles) estás en problemas.
Restablecer Monica
55
Es por eso que usa pestañas en lugar de espacios, o un IDE que comprende cómo convertir pestañas en bloques de cuatro espacios.
Robert Harvey
@ K.Gkinis: Las sangrías no son invisibles. Solo el espacio en blanco al final de las líneas es invisible, pero esto no es significativo en ningún idioma. Solo si mezclas pestañas y espacios te meterás en problemas. Entonces no hagas eso.
JacquesB
@JacquesB: el problema con la visibilidad / invisibilidad de la sangría es que, como humano, a menudo no se puede distinguir la diferencia entre espacios y una pestaña, mientras que la computadora sí puede hacerlo. Entonces, mientras la sangría es visible, la forma en que la computadora interpreta la sangría puede ser diferente. Ese es el verdadero problema: cuando la computadora trata a los personajes invisibles de manera diferente a los humanos. Los humanos miden la sangría como la distancia en una pantalla, las computadoras pueden medirla como un número literal de caracteres. Esa es la parte invisible.
Bryan Oakley
@BryanOakley: Sí, es por eso que no debes mezclar pestañas y espacios en sangría.
JacquesB