En muchos lenguajes (una amplia lista, de C a JavaScript):
- las comas
,
separan los argumentos (por ejemplofunc(a, b, c)
), mientras que - punto y coma
;
separan instrucciones secuenciales (pinstruction1; instruction2; instruction3
. ej .).
Entonces, ¿por qué esta asignación se invierte en los mismos idiomas para bucles for :
for ( init1, init2; condition; inc1, inc2 )
{
instruction1;
instruction2;
}
en lugar de (lo que me parece más natural)
for ( init1; init2, condition, inc1; inc2 )
{
instruction1;
instruction2;
}
?
Claro, for
es (normalmente) no una función, pero los argumentos (es decir init
, condition
, increment
) se comportan más como argumentos de una función de una secuencia de instrucciones.
¿Se debe a razones históricas / una convención, o hay una buena razón para el intercambio de ,
y ;
en bucles?
programming-languages
syntax
loops
Piotr Migdal
fuente
fuente
;
no|
?" (o ¿Por qué usamos 'otra cosa' no 'en otro caso'? )) que no es el caso de un idioma, pero un gran número de ellos. Una respuesta que, por ejemplo, "se hizo en C como una abreviatura del ciclo while (y las declaraciones múltiples para inc se pensaron solo más tarde), y la gente no quería cambiarla para evitar la irritación de los programadores", estaría perfectamente bien.Respuestas:
Técnicamente, el mapeo no se "invierte".
En realidad, lo que tenemos aquí es un contexto sintáctico diferente donde los mismos símbolos se usan de manera diferente. No estamos comparando like con like, por lo que no hay mapeo ni argumento sólido para un mapeo consistente basado en la consistencia semántica.
Entonces, ¿por qué no hacerlo al revés?
Bueno, creo que las razones provienen del significado "natural" de
,
y;
. En el idioma escrito en inglés, un punto y coma es una ruptura "más fuerte" que una coma, y el glifo para punto y coma es más visible que una coma. Esas dos cosas se combinan para hacer que la disposición actual parezca (¡para mí!) Más natural.Pero la única forma de saber con certeza por qué se hizo la elección de la sintaxis sería si los diseñadores de C pudieran decirnos qué estaban pensando en ~ 1970. Dudo que tengan un claro recuerdo de las decisiones técnicas tomadas tan atrás en el tiempo.
No conozco ningún lenguaje antes de C que use una sintaxis similar a C para bucles "for":
Donal Fellows señala que BCPL y B no tenían una construcción equivalente.
Los equivalentes FORTRAN, COBOL y Algol-60 (y Pascal) fueron menos expresivos y tenían sintaxis que no se parecían a la sintaxis C "para".
Pero los lenguajes como C, C ++ y Java que surgieron después de C, claramente toman prestada su sintaxis "for" de C.
fuente
,
vs;
) es (ruptura más débil versus más fuerte), en lugar de (divisor de secuencia vs tupla), ¿verdad? Aún así, para mí no es obvio si los argumentos o las declaraciones necesitan pausas más fuertes (como en muchos casos para una secuencia de declaraciones, las pausas son implícitas (ver, por ejemplo, JavaScript (pi++[line break]j++
. Ej .)), Pero al menos ahora entiendo por qué la convención actual no está "obviamente invertido".FOR i = e1 TO e2 BY e3 DO c
(expresiones e1..e3, comando c), que se parece más a la sintaxis de BASIC. Fuentefor
sintaxis se introdujo en C (no en B o BCPL).Escribimos bucles como:
El lenguaje podría haberse definido para que los bucles se vean así:
Sin embargo, piense en el mismo bucle implementado usando un bucle while:
Observe que las declaraciones
x=0
yx++
son, terminadas en punto y coma. No son expresiones como las que tendría en una llamada de función. Los puntos y comas se usan para separar las declaraciones, y dado que dos de los tres elementos en un bucle for son declaraciones, eso es lo que se usa allí. Un bucle for es solo un atajo para tal bucle while.Además, los argumentos realmente no actúan como argumentos para una función. El segundo y el tercero son evaluados repetidamente. Es cierto que no son una secuencia, pero tampoco son argumentos de función.
Además, el hecho de que puede usar comas para tener varias declaraciones en el ciclo for es en realidad algo que puede hacer fuera del ciclo for.
es una declaración perfectamente válida incluso fuera de un ciclo for. Sin embargo, no conozco ningún uso práctico fuera del ciclo for. Pero el punto es que las comas siempre subdividen las declaraciones; No es una característica especial del bucle for.
fuente
x = 0; y = 0;
y (dentro del corchete)x++; y++;
...;
es natural para una secuencia de declaraciones , no necesariamente separando ninguna declaración (entonces, ¿es solo que los gustos difieren?). Y en la convención actual, uno ocasionalmente termina separando secuencias de declaraciones con comas de todos modos ...(foo)?bar++, qux++:bletch
--- dónde quieres que la?:
expresión haga dos cosas en lugar de solo una? El valor de retorno sifoo
es verdadero esqux
, pero ambosbar
yqux
se incrementan.En C y C ++, este es el operador de coma, no solo una coma.
La gramática para un
for
bucle es algo así comoEn el caso de su pregunta:
Tenga en cuenta que el operador de coma le permite realizar múltiples acciones en una declaración (como lo ve el compilador). Si su sugerencia se implementara, habría una ambigüedad en la gramática sobre cuándo el programador tenía la intención de escribir una declaración de operador de coma o un separador.
En resumen,
;
significa el final de una declaración. Unfor
bucle es una palabra clave seguida de una lista de declaraciones opcionales rodeadas por()
. La declaración de operador de coma permite el uso de,
en una sola declaración.fuente
for
bucle permite explícitamente una declaración (declaración) como su primera parte. (C ++ permitió declaraciones en la mitad de la función, a diferencia de su predecesor C89). No puede generalizar dichas declaraciones en todos los idiomas, incluso para 2 idiomas tan cercanos como C y C ++.for ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
de C yfor ( for-init-statement; conditionopt ; expressionopt ) statement
de C ++ --- El ';' no solo significa un terminador de declaración. Un ciclo for no va seguido de declaraciones encerradas en ().No hay inversión conceptual.
Los puntos y coma en C representan divisiones más importantes que las comas. Separan declaraciones y declaraciones.
Las divisiones principales en el ciclo for es que hay tres expresiones (o una declaración y dos expresiones) y un cuerpo.
Las comas que ves en C para bucles no son parte de la sintaxis del bucle for específicamente. Son solo manifestaciones del operador de coma.
Las comas son separadores principales entre argumentos en llamadas a funciones y entre parámetros en declaraciones de funciones, pero no se utilizan punto y coma. El bucle for es una sintaxis especial; No tiene nada que ver con funciones o llamadas a funciones.
fuente
Tal vez esto sea algo específico para C / C ++, pero publico esta respuesta, porque la sintaxis de los idiomas que describió está influenciada principalmente por la sintaxis C.
Además de que las preguntas respondidas anteriormente son ciertas, desde un punto de vista técnico, eso también se debe a que en C (y C ++) la coma es en realidad un operador , que incluso puede sobrecargar . El uso de un operador de punto y coma (
operator;()
) posiblemente dificultaría la escritura de compiladores, ya que el punto y coma es el terminador de expresión axiomático.Lo que hace que esto sea interesante es el hecho de que la coma se usa ampliamente como separador en todo el lenguaje. Parece que el operador de coma es una excepción, que se usa principalmente para que
for
funcionen los bucles con múltiples condiciones, entonces, ¿cuál es el problema?De hecho,
operator,
está diseñado para hacer lo mismo que en las definiciones, listas de argumentos, etc.: ha sido creado para separar expresiones, algo que la construcción sintáctica,
no puede hacer. Solo puede separar lo que se ha definido en el estándar.Sin embargo, el punto y coma no se separa, termina . Y esto también es lo que nos lleva de vuelta a la pregunta original:
La coma separa las expresiones en las tres partes del bucle, mientras que el punto y coma termina una parte (inicialización, condición o idea de último momento) de la definición del bucle.
Es posible que los lenguajes de programación más nuevos (como C #) no permitan sobrecargar el operador de coma, pero lo más probable es que mantuvieran la sintaxis, porque cambiarlo no parece natural.
fuente
for
declaración, el;
símbolo se usa claramente como separador. Separa las 3 partes sintácticas de la declaración. No hay un tercer punto y coma para "terminar" la lista de expresiones progresivas. Está terminado por un token diferente -)
.Para mí se usan más significados menos similares a su sentido lingüístico. Las comas se usan con listas y punto y coma con partes más separadas.
En
func(a, b, c)
tenemos una lista de argumentos.instruction1; instruction2; instruction3
es quizás una lista pero una lista de instrucciones separadas e independientes.Mientras
for ( init1, init2; condition; inc1, inc2 )
que tenemos tres partes separadas: una lista de inicializaciones, una condición y una lista de expresiones de incremento.fuente
La forma más fácil de verlo es la siguiente:
es:
En otras palabras, esas cosas x = 0 son en realidad una declaración / instrucciones en lugar de un parámetro. Inserta una declaración allí. Por lo tanto, están separados por punto y coma.
De hecho, no hay forma de que estén separados por comas. ¿Cuándo hace la última vez que inserta cosas como x <10 como parámetro? Lo hace si desea computarizar x <10 una vez e insertar el resultado de esa operación como parámetro. Entonces, en el mundo de las comas, pondría x <10 si desea pasar el valor de x <0 a una función.
Aquí especifica que el programa debe verificar x <10 cada vez que se pasa el bucle. Entonces eso es una instrucción.
x ++ es definitivamente otra instrucción.
Esas son todas las instrucciones. Entonces están separados por punto y coma.
fuente
for
switch
oreturn
dentro de la definición del ciclo for (es decirfor(int i = 0; if(i > 1024) { return; } ; switch (i % 3) { case 0; case 1: i++; case 2: i++; } ) { ... }
) --- no puede. No es una declaración. En cambio, se define comofor ( {<expression>}? ; {<expression>}? ; {<expression>}? ) <statement>
int i = 0
Definitivamente NO es una expresión. El conjunto de reglas que describen una expresión es bastante complejo, considerando lo que puede constituir una expresión, pero la construcciónTYPE NAME = EXPRESSION
no coincide con ninguna de esas reglas.