La definición de "lenguaje C-Style" prácticamente se puede simplificar a "usa llaves ( {}
)". ¿Por qué usamos ese carácter en particular (y por qué no algo más razonable, como []
que no requiere la tecla Mayús al menos en los teclados de EE. UU.)?
¿Existe algún beneficio real para la productividad del programador que provenga de estos aparatos, o deberían los nuevos diseñadores de lenguaje buscar alternativas (es decir, los chicos detrás de Python)?
Wikipedia nos dice que C usa dichos aparatos ortopédicos, pero no por qué. Una declaración en el artículo de Wikipedia sobre la Lista de lenguajes de programación basados en C sugiere que este elemento de sintaxis es algo especial:
En términos generales, los lenguajes de la familia C son aquellos que usan la sintaxis de bloque tipo C (incluidas las llaves para comenzar y finalizar el bloque) ...
fuente
Respuestas:
Dos de las principales influencias para C fueron la familia de lenguajes Algol (Algol 60 y Algol 68) y BCPL (de donde C toma su nombre).
De http://www.princeton.edu/~achaney/tmve/wiki100k/docs/BCPL.html
Desde http://progopedia.com/language/bcpl/
Dentro de BCPL, a menudo se ven llaves, pero no siempre. Esta era una limitación de los teclados en ese momento. Los caracteres
$(
y$)
eran lexicográficamente equivalentes a{
y}
. Los dígrafos y los trigrafos se mantuvieron en C (aunque un conjunto diferente para el reemplazo de llaves )??<
y??>
).El uso de llaves se refinó aún más en B (que precedió a C).
De la referencia de los usuarios a B de Ken Thompson:
Hay indicios de que las llaves se usaron como mano corta para
begin
yend
dentro de Algol.De http://www.bobbemer.com/BRACES.HTM
El uso de corchetes (como reemplazo sugerido en la pregunta) se remonta aún más. Como se mencionó, la familia Algol influyó en C. Dentro de Algol 60 y 68 (C se escribió en 1972 y BCPL en 1966), el corchete se usó para designar un índice en una matriz o matriz.
Como los programadores ya estaban familiarizados con los corchetes para matrices en Algol y BCPL, y las llaves para bloques en BCPL, había poca necesidad o deseo de cambiar esto al hacer otro idioma.
La pregunta actualizada incluye un anexo de productividad para el uso de llaves y menciona python. Hay otros recursos que hacen este estudio, aunque la respuesta se reduce a "Es anecdótico, y a lo que está acostumbrado es con lo que es más productivo". Debido a las habilidades que varían ampliamente en la programación y la familiaridad con los diferentes lenguajes, estos se vuelven difíciles de explicar.
Ver también: Desbordamiento de pila ¿Hay estudios estadísticos que indiquen que Python es "más productivo"?
Gran parte de las ganancias dependerían del IDE (o falta de) que se use. En editores basados en vi, al colocar el cursor sobre una apertura / cierre coincidente y presionar
%
, el cursor se moverá al otro carácter coincidente. Esto es muy eficiente con lenguajes basados en C en los viejos tiempos, menos ahora.Una mejor comparación sería entre
{}
ybegin
/end
cuáles fueron las opciones del día (el espacio horizontal era precioso). Muchos lenguajes Wirth se basaron en unabegin
yend
estilo (Algol (mencionado anteriormente), Pascal (muchos están familiarizados con), y la familia Modula).Tengo dificultades para encontrar alguno que aísle esta característica específica del lenguaje; en el mejor de los casos, lo que puedo hacer es demostrar que los lenguajes de llaves son mucho más populares que los idiomas de inicio y final y es una construcción común. Como se mencionó anteriormente en el enlace Bob Bemer, la llave se usó para facilitar la programación como taquigrafía.
Por qué Pascal no es mi lenguaje de programación favorito
Lo cual es todo lo que se puede decir: su familiaridad y preferencia.
fuente
{
y}
son??<
y??>
. Los dígrafos (introducidos por la enmienda de 1995) son<%
y%>
. Los trígrafos se expanden en todos los contextos, en una fase de traducción muy temprana. Los dígrafos son tokens y no se expanden en literales de cadena, constantes de caracteres o comentarios.x:=(c|s1|s2)
lugar de C'sx=c?s1|s2
. Del mismo modo, esto se aplica a las declaraciones if y case . ¢ BTW: A68 es de donde el shell obtuvo su esac & fi ¢Los corchetes
[]
son más fáciles de escribir, desde el terminal IBM 2741 que fue "ampliamente utilizado en el sistema operativo Multics" , que a su vez tenía a Dennis Ritchie, uno de los creadores del lenguaje C como miembro del equipo de desarrollo .¡Tenga en cuenta la ausencia de llaves en el diseño de IBM 2741!
En C, los "corchetes" se "toman", ya que se usan para matrices y punteros . Si los diseñadores de lenguaje esperaran que las matrices y los punteros fueran más importantes / utilizados con más frecuencia que los bloques de código (lo que parece una suposición razonable a su lado, más sobre el contexto histórico del estilo de codificación a continuación), eso significaría que las llaves se irían a "menos importantes "sintaxis.
La importancia de las matrices es bastante evidente en el artículo El desarrollo del lenguaje C de Ritchie. Incluso hay una suposición explícitamente establecida de "prevalencia de punteros en los programas en C" .
Para una mejor comprensión del contexto histórico y el estilo de codificación de la época en que se creó el lenguaje C, uno debe tener en cuenta que "el origen de C está estrechamente relacionado con el desarrollo de Unix" y, específicamente, que portar el sistema operativo a un PDP- 11 "condujo al desarrollo de una versión temprana de C" ( fuente de citas ). Según Wikipedia , "en 1972, Unix fue reescrito en el lenguaje de programación C" .
El código fuente de varias versiones antiguas de Unix está disponible en línea, por ejemplo, en el sitio The Unix Tree . De varias versiones presentadas allí, la más relevante parece ser la Segunda Edición de Unix con fecha de 1972-06:
Puede explorar y estudiar el código fuente C desde la página Unix (V2) de la Segunda Edición para tener una idea del estilo de codificación típico de la época.
Un ejemplo destacado que respalda la idea de que en aquel entonces era bastante importante para el programador poder escribir corchetes con facilidad se puede encontrar en el código fuente V2 / c / ncc.c :
Es interesante observar cómo la motivación pragmática de elegir personajes para denotar elementos de sintaxis del lenguaje en función de su uso en aplicaciones prácticas específicas se asemeja a la Ley de Zipf como se explica en esta excelente respuesta ...
... con la única diferencia de que la longitud en la declaración anterior se sustituye por / generalizada como velocidad de escritura.
fuente
grep -Fo
me dice los*.c
archivos del código fuente de CPython (rev. 4b42d7f288c5 porque eso es lo que tengo a mano), que incluye libffi, contiene 39511{
(39508{
, no sé por qué dos llaves no están cerradas), pero solo 13718[
(13702[
) Eso es contar las ocurrencias en cadenas y en contextos no relacionados con esta pregunta, por lo que esto no es realmente exacto, incluso si ignoramos que la base del código puede no ser representativa (tenga en cuenta que este sesgo podría ir en cualquier dirección). Aún así, un factor de 2.8?C (y posteriormente C ++ y C #) heredó su estilo de refuerzo de su predecesor B , que fue escrito por Ken Thompson (con contribuciones de Dennis Ritchie) en 1969.
Este ejemplo es de la referencia de usuarios a B de Ken Thompson (a través de Wikipedia ):
B se basó nuevamente en BCPL , un lenguaje escrito por Martin Richards en 1966 para el sistema operativo Multics. El sistema de arriostramiento de B utilizaba solo llaves redondas, modificadas por caracteres adicionales (Ejemplo de factoriales de impresión de Martin Richards, a través de Wikipedia )
Las llaves usadas en B y en los lenguajes posteriores "{...}" es una mejora que Ken Thompson hizo sobre el estilo de llave compuesto original en BCPL "$ (...) $".
fuente
$( ... $)
formato es equivalente a{ ... }
en el lexer en BCPL, al igual??< ... ??>
que{ ... }
en C. La mejora entre los dos estilos está en el hardware del teclado, no en el idioma.