lolpython loops decrement lolcode

loops - lolpython - ¿De qué sirve la operación de lazo NERFIN en LOLCODE?



decrement (1)

Lo que dice la especificación sobre el tema:

Los bucles de iteración tienen la forma:

IM IN YR <label> <operation> YR <variable> [TIL|WILE <expression>] <code block> IM OUTTA YR <label>

Donde <operación> puede ser UPPIN (incremento en uno), NERFIN (disminución en uno) o cualquier función unaria. Esa operación / función se aplica a la <variable>, que es temporal y local al bucle. La TIL <expresión> evalúa la expresión como TROOF: si se evalúa como FAIL, el ciclo continúa una vez más, si no, la ejecución del ciclo se detiene y continúa después de la coincidencia IM OUTTA YR <etiqueta>. El WILE <expresión> es el inverso: si la expresión es WIN, la ejecución continúa; de lo contrario, el ciclo se cierra.

Pregunta

Mi queja con la especificación es la combinación de:

  • la falta de un inicializador de variables de bucle
  • el hecho de que es temporal y local para el ciclo

Según lo entiendo, esto significa que tiene que comenzar en 0.

Si bien eso está bien para la mayoría de los usos de UPPIN , está totalmente fuera de la mayoría de mis usos previstos de NERFIN . Mis usos más comunes de una variable de ciclo decreciente en otros idiomas son las expresiones idiomáticas y operaciones de repetición "repeat n times ( n not reused)", que de todos modos no serían una buena idea en LOLCODE.

¿Es posible utilizar NERFIN para obtener un decremento de bucle de n a 1 o 0 de una manera que sea menos detallada que los equivalentes con UPPIN o las formas sin operación de bucle?

Comparación de alternativas

Imprimir 5 4 3 2 1 con la variante UPPIN :

IM IN YR LOOPZ UPPIN YR COWNTR TIL BOTH SAEM COWNTR AN 5 VISIBLE DIFF OF 5 AN COWNTR IM OUTTA YR LOOPZ

Pros: conciso.
Contras: la variable de ciclo real no es accesible directamente.

Con la variante sin operación:

I HAS A COWNTR ITZ 5 IM IN YR LOOPZ VISIBLE COWNTR COWNTR R DIFF OF COWNTR AN 1 BOTH SAEM COWNTR AN 0, O RLY? YA RLY, GTFO, OIC IM OUTTA YR LOOPZ

Pros: la variable de bucle está directamente disponible.
Contras: más largo.

Lo mejor que puedo obtener con NERFIN :

IM IN YR LOOPZ NERFIN YR COWNTR TIL BOTH SAEM COWNTR AN -5 VISIBLE SUM OF 5 AN COWNTR IM OUTTA YR LOOPZ

Pros: err ... usa NERFIN ?
Contras: la variable de ciclo no es accesible directamente; menos legible (¡ UPPIN !) que la variante UPPIN ; sin ganancia en verbosidad

Pregunta TLDR, repetida

¿Es posible utilizar NERFIN para obtener un decremento de bucle de n a 1 o 0 de una manera que sea menos detallada que los equivalentes con UPPIN o las formas sin operación de bucle?

Estoy usando el intérprete lci en el nivel de especificación de lenguaje 1.2.


Hubo una discusión de diseño de 2007 sobre este tema exacto. El consenso en ese momento parecía sugerir agregar un FROM como una solución que el grupo de trabajo quería rastrear rápidamente en 1.2:

http://forum.lolcode.com/viewtopic.php?pid=2484

El problema se presentó y no se incluyó en la especificación 1.2. Sin embargo, aparentemente está en la especificación 1.3:

http://lolcode.com/proposals/1.3/loop2

Aún en proceso, sin embargo. Lo revisé y todavía no está en la rama "futura" del repositorio. Podemos ver esto mirando el código del intérprete de bucle. A partir del 8/24/2011 (en la revisión 72c983d0667d4d650657e1b7c5f4c7054096b0dd), de todos modos, siempre asigna inicialmente la variable de ciclo un NUMBR de 0:

https://github.com/justinmeza/lci/blob/72c983d0667d4d650657e1b7c5f4c7054096b0dd/interpreter.c#L3434

Sin embargo, incluso con la especificación anterior, debería ser teóricamente posible utilizar un TROOF en combinación con una prueba en contra de -1 para permitir una forma relativamente limpia de conteo regresivo de 5 a 0:

BTW countdown-test.lol CAN HAS STDIO? HAI 1.2 HOW DUZ I COUNTDOWN YR BOWNDZ I HAS A FIRSTIES FIRSTIES R WIN IM IN YR LOOPZ NERFIN YR COWNTR TIL BOTH SAEM COWNTR AN -1 FIRSTIES O RLY? YA RLY COWNTR R BOWNDZ FIRSTIES R FAIL OIC VISIBLE COWNTR IM OUTTA YR LOOPZ IF U SAY SO COUNTDOWN 5 KTHXBYE

Desafortunadamente, hay un "hack de eficiencia" que impide que el código dentro de un bucle modifique la variable de bucle usando R :

https://github.com/justinmeza/lci/blob/a6ef5811e8eb98935a16600b799bccbe4adffdde/interpreter.c#L3408

Sin embargo, como esto parece ser un error en el código en comparación con una omisión en la especificación, es más probable que se solucione antes de la versión 1.3. Parcheando interpreter.c para decir if (0 && stmt->update->type == ET_OP) hace que el código de countdown-test.lol ejecute como se esperaba. Puede ser una solución provisional adecuada para las implementaciones 1.2 LOLCODE existentes si no tiene que compartir el código con las instalaciones sin parchear.