He pasado la mayor parte de los últimos años trabajando principalmente con C # y SQL. Todos los programadores con los que trabajé durante ese tiempo tenían la costumbre de colocar la llave de apertura de una función o declaración de flujo de control en una nueva línea. Asi que ...
public void MyFunction(string myArgument)
{
//do stuff
}
if(myBoolean == true)
{
//do something
}
else
{
//do something else
}
Siempre me ha llamado la atención el desperdicio de espacio, especialmente en las declaraciones if / else. Y sé que existen alternativas en versiones posteriores de C #, como:
if(myBoolean == true)
//do something on one line of code
Pero casi nadie los usó. Todos hicieron lo de rizar-apoyarse-en-nueva línea.
Luego volví a hacer JavaScript después de una larga ausencia. En mi memoria, los desarrolladores de JavaScript solían hacer exactamente lo mismo, pero con todas las nuevas bibliotecas y cosas elegantes, la mayoría de los desarrolladores ponen la llave de apertura después de la declaración:
function MyJavaScriptFunction() {
//do something
}
Puede ver el sentido en esto, ya que el uso de cierres y punteros de función se ha vuelto popular en JavaScript, ahorra mucho espacio y hace que las cosas sean más legibles. Entonces me pregunté por qué no se veía como lo hecho en C #. De hecho, si prueba la construcción anterior en Visual Studio 2013, en realidad lo reformatea por usted, ¡colocando la llave de apertura en una nueva línea!
Ahora, acabo de ver esta pregunta en Code Review SE: https://codereview.stackexchange.com/questions/48035/questions-responses-let-me-tell-you-about-you En el que aprendí eso en Java, un lenguaje con el que no estoy demasiado familiarizado, se considera de rigor abrir sus llaves justo después de la declaración, en la moda moderna de JavaScript.
Siempre había entendido que C # fue modelado originalmente después de Java, y mantuvo muchos de los mismos estándares de codificación basal. Pero en este caso, parece que no. Entonces supongo que debe haber una buena razón: ¿cuál es la razón? ¿Por qué los desarrolladores de C # (y Visual Studio) aplican la apertura de llaves en una nueva línea?
fuente
if(myBoolean == true)
tiene poco sentido para mí. Mientras estamos en eso, mientras que noif ((myBoolean == true) == true)
? Justoif (myBoolean)
y eso es suficiente. Lo siento, una mascota mía.Respuestas:
La llave al final de la línea es el antiguo estándar K&R C, del libro de Brian Kernighan y Dennis Ritchie, The C Programming Language , que publicaron en 1978 después de inventar el sistema operativo UNIX y el lenguaje de programación C (creo que C era diseñado principalmente por Ritchie), en AT&T.
Solía haber guerras de llamas sobre "el único estilo verdadero de aparatos ortopédicos".
Ritchie inventó el lenguaje C, y Kernighan escribió el primer tutorial, cuando las pantallas de la computadora solo mostraban unas pocas líneas de texto. De hecho, el desarrollo de UNICS (luego UNIX) comenzó en un DEC PDP-7, que utilizaba una máquina de escribir, una impresora y una cinta de papel para una interfaz de usuario. UNIX y C se terminaron en el PDP-11, con terminales de texto de 24 líneas. Por lo tanto, el espacio vertical era realmente muy importante. Todos tenemos pantallas ligeramente mejores e impresoras de mayor resolución hoy, ¿verdad? Quiero decir, no sé sobre ti, pero tengo tres (3) pantallas de 24 "y 1080p frente a mí en este momento. :-)
Además, gran parte de ese pequeño libro The C Programming Language son ejemplos de código que colocar los corchetes en los extremos de las líneas en lugar de en sus propias líneas supuestamente ahorró una cantidad considerable de dinero en la impresión.
Lo realmente importante es la coherencia en todo un proyecto, o al menos dentro de un archivo de código fuente dado.
También hay estudios científicos que muestran que el aparato ortopédico en su propia línea (de hecho, con sangría al mismo nivel que el código) mejora la comprensión del código a pesar de lo que las personas piensan que piensan de la estética. Le deja muy claro al lector, visual e instintivamente, qué código se ejecuta en qué contexto.
C # siempre ha apoyado la evaluación de un solo comando después de una expresión de ramificación, por cierto. De hecho, eso es lo único que hace, incluso ahora. Poner el código entre llaves después de una expresión de ramificación solo hace que ese comando sea un goto (el compilador crea el alcance usando las instrucciones jmp). C ++, Java, C # y JavaScript se basan más o menos en C, con las mismas reglas de análisis subyacentes, en su mayor parte. Entonces, en ese sentido, C # no está "basado en Java".
En resumen, este es un tema religioso / de guerra de llamas. Pero hay estudios que dejan bastante claro que organizar el código en bloques mejora la comprensión humana . Al compilador no podría importarle menos. Pero esto también está relacionado con la razón por la que nunca pongo una línea de código después de una rama sin llaves: es demasiado fácil para mí u otro programador colocar otra línea de código allí más tarde y dejar de lado el hecho de que no ejecutar en el mismo contexto con la línea justo antes o después de ella.
EDITAR : solo mire el error de Apple
goto fail
para obtener un ejemplo perfecto de este problema exacto, que tuvo graves consecuencias en el mundo real.se convierte en ...
En este caso, se
doSomethingElse()
ejecuta cada vez, independientemente del resultado de la prueba, pero debido a que está sangrado al mismo nivel que ladoSomething()
declaración, es fácil pasarla por alto. Esto no es realmente discutible; Los estudios respaldan esto. Esta es una gran fuente de errores introducidos en el código fuente durante el mantenimiento.Aún así, admito que la sintaxis de cierre de JavaScript se ve un poco tonta con llaves en sus propias líneas ... estéticamente. :-)
fuente
begin
yend
en lugar de llaves, lo que hace que tales errores sean realmente difíciles de omitir, y también es más estricto con respecto a la colocación de punto y coma, pero gastar El año pasado, 4 días de depuración de un problema en C incrustado que se debió a la falta de colocación de llaves ... ¡Creo que debería haber una opción de compilador que haga que las llaves sean obligatorias para las declaraciones de control!La razón por la que los desarrolladores de C # lo hacen es porque es la configuración predeterminada del formateador automático de Visual Studio. Si bien esta configuración se puede cambiar, la mayoría de las personas no, y por lo tanto, todos los desarrolladores de un equipo tienen que ir con la mayoría.
En cuanto a por qué este es el valor predeterminado en Visual Studio, no lo sé.
fuente
Como planteé la hipótesis en esta respuesta aquí, https://softwareengineering.stackexchange.com/a/159081/29029 , supongo que la decisión de ir con el refuerzo de Allman podría ser un signo de la herencia de Pascal, dado que Hejlsberg creó a Delphi antes de diseñar C # . Igual que el caso Pascal para nombres de métodos.
Personalmente creo en seguir el adagio "en Roma haz lo que hacen los romanos". Uso Allman's en C #, pero K&R en Java. Estoy tan acostumbrado a eso que cambiar la convención de cualquier manera me molesta.
Creo que cierta diversidad de convenciones es realmente beneficiosa para un desarrollador "multilingüe", ya que ayuda a recordar en qué idioma están codificando en este momento y facilita la diferenciación de varios hábitos. Es un equivalente mental de la memoria muscular, por así decirlo.
fuente
goto fail
uso de la sangría para controlar el flujo del programa es lo que los humanos naturalmente quieren hacer, así que lo que ve es lo que se ejecuta. Si está indentado mal, simplemente no funciona. Tener que decodificar lo que significan esas llaves, si realmente reflejan la sangría, es un trabajo adicional además de comprender el programa. La sangría es redundante para las llaves, entonces, ¿por qué los programadores la usan si las llaves son útiles? La anidación profunda es ininteligible en cualquier idioma. Jus 'sayin'.La convención que asocias con Java es el estilo K&R, o el "Estilo de una llave verdadera", y originalmente proviene de C. Esta página con sangría del venerable Archivo Jargon muestra la antigüedad de la distinción.
Siempre he pensado que el estilo de Allman y sus variantes son un reflejo de cómo piensan los autores sobre el código, elevando los delimitadores de bloque al nivel de palabras clave similares a cómo algunos idiomas usan "comenzar" y "terminar" alrededor de bloques de código.
fuente