Pregunta similar se cerró en SO.
A veces, cuando estamos programando, encontramos que alguna estructura de control particular sería muy útil para nosotros, pero no está directamente disponible en nuestro lenguaje de programación.
¿Qué estructuras de control alternativas crees que son una forma útil de organizar la computación?
El objetivo aquí es obtener nuevas formas de pensar sobre la estructuración del código, a fin de mejorar la fragmentación y el razonamiento.
Puede crear una sintaxis / semántica deseable que no esté disponible ahora o citar una estructura de control menos conocida en un lenguaje de programación existente.
Las respuestas deben dar ideas para un nuevo lenguaje de programación o mejorar un lenguaje real.
Piense en esto como una lluvia de ideas, así que publique algo que piense que es una idea loca pero que puede ser viable en algún escenario.
Se trata de una programación imperativa.
Respuestas:
OK, esta es una pregunta divertida.
También me gustaría tener un general
else
para while y para bucles, para cuando la condición no es cierta en la primera prueba:Esto evita el recálculo incómodo de la condición o el almacenamiento en una variable.
fuente
while ... else
construcción de la forma en que Macneil la describe a PHP. Creo que es una gran idea, porque "aquí están los resultados / no hubo resultados" es un idioma bastante común en las aplicaciones web.¿Por qué no mezclar algunas respuestas en una?
Una sintaxis de construcción de control de flujo generalizada y extensible en un lenguaje imperativo sería bastante útil y entretenida. Hasta que aparezca, supongo que solo usaré Lisp o algo así.
fuente
seventh { ... }
.Estructuras de control como funciones.
Quiero
for
,if
,else
,while
, etc que son funciones, no estructuras especiales.Quiero
return
,try/except
ygoto
ser derivados de continuaciones.Por supuesto, esto tiene menos que ver con una estructura de control particular y más con la forma en que ve las estructuras de control en general, las estructuras meta de control.
fuente
for
,if
,else
, ywhile
como las funciones que me hace inferir que los parámetros a esas funciones deben ser ejecutados con pereza con el fin de comportarse de la misma que las construcciones originales. Tener la capacidad de hacer una ejecución perezosa sería bueno.return
, excepciones, etc. Pero ahora el programador experto tiene una poderosa herramienta adicional en su caja de herramientas si surge la necesidad. Además, los idiomas de mi humilde opinión no deberían ser "tontos". Los idiomas deben tener la capacidad de soportar una mayor experiencia y el crecimiento del conocimiento de CS.El artículo vinculado definitivamente lo hace bien sobre los N + 1/2 Loops de Donald Knuth . Expresado en C / C ++ / Java:
Esto es útil para leer líneas o caracteres de un archivo, probar si ha alcanzado EOF y luego procesarlo. Estoy tan acostumbrado a ver
for(;;)..if(..)break;
aparecer el patrón que es idiomático para mí. (Antes de leer el artículo de Knuth, reimpreso en el libro Literate Programming , este solía ser un "wtf?").Knuth sugirió las palabras clave
loop/while/repeat
:Donde
S
yT
son marcadores de posición para una serie de cero o más declaraciones, yC
es una condición booleana. Si no hubiera unaS
declaración, entonces sería un ciclo while, y si no hubiera unaT
declaración, sería un ciclo do.Esta construcción en sí misma podría generalizarse permitiendo cero o más
while C
cláusulas, haciéndola perfecta para expresar bucles infinitos y luego algunas condiciones más raras que necesitarían dos comprobaciones.En el mismo artículo, Knuth sugirió un mecanismo de señalización que sería una versión local de lanzar / atrapar excepciones (como alternativa al uso de goto).
¿Para mi? Deseo que Java sea compatible con la optimización de llamadas de cola, para poder expresar cualquier estructura de control general según sea necesario.
Actualización: Olvidé mencionar que muchos programadores de C / C ++ / Java eluden este usando una asignación incrustada en la condición de
while
:El uso de los términos de constructo de Knuth, esto es admisible cuando
S
yC
se pueden combinar en una sola expresión. Algunas personas odian ver la tarea incrustada arriba, mientras que otras odian verlabreak
en lofor (;;)
anterior. Pero cuandoS
yC
no se pueden combinar, como cuandoS
tiene múltiples declaraciones, estafor (;;)
es la única alternativa sin repetir el código. La otra alternativa es simplemente duplicar elS
código:La
loop/while/repeat
alternativa de Knuth parece mucho mejor.fuente
repeat-until
ciclo de Pascal .do while ... loop until
: tanto la precondición como la poscondición son opcionales, y recuerdo (vagamente) usar ambas en un bucle. Para su condición media, está el Adaexit when ...;
. La ventaja claveif ... break;
es que puede escribirexit loopname when ...;
para salir de múltiples (pero no necesariamente) bucles anidados a la vez. Probablemente un poco más visible que ese descanso también.El lenguaje BCPL tenía una
valueof
expresión que podía usarse para convertir una secuencia de declaraciones en una sola expresión:Donde
some series of statements
puede ser cualquier cosa y todo sevalueof
evalúav
.Esto podría ser útil en Java para cuando necesite calcular un argumento para llamar a
this()
osuper()
(lo que requiere que no suceda nada antes). Por supuesto, podría escribir un método separado, pero eso podría ser un problema si necesita pasar muchos valores locales para el contexto.Si puede usar las
final
variables que necesita, ya puede hacer unvalueof
en Java utilizando clases internas anónimas:fuente
({ statement1; statement2; ...; result-expr; })
. También he visto cosas similares en otros lugares, pero no recuerdo dónde. Probablemente todo copiado de BCPL, sin embargo.hace lo mismo que:
hace lo mismo que:
fuente
unless
.En una nota diferente, me gustaría ver un mejor soporte para iteradores en lenguajes de programación. En particular, para cuando quieres bajar dos colecciones en pares :
Es posible que algunos lenguajes dinámicos ya tengan esto, o que sean fácilmente compatibles a través de bibliotecas y macros, pero creo que esto está en el espíritu de su pregunta.
Si los dos conjuntos no son del mismo tamaño, podría generar una excepción o podría tener un
else
bucle posterior para indicar que hubo una diferencia en los tamaños.Naturalmente, podría generalizar esto para bajar tres o más listas.
Actualización: También sería útil hacer el producto cartesiano entre iterables:
que no sería más que bucles anidados:
Me preocupa un poco que entre las dos notaciones que he proporcionado aquí haya una diferencia de O (n) y O (n ^ 2) en el número de pares, con solo el cambio de un solo carácter.
fuente
for a, b, c in itertools.product(iter1, iter2, iter3):
le da el producto cartesiano evaluado perezosamente. ¿Que es eso? ¿Quieres permutaciones y combinaciones de un iterador dado también?itertools.permutations
,itertools.combinations
.Existe el llamado "bucle de Dijkstra" (también llamado "bucle guardado de Dijkstra"). Se definió en The Guarded Command Language (GCL) . Puede encontrar información sobre la sintaxis y la semántica en el artículo de Wikipedia anterior en la sección 6 Repetición: do .
Hoy en día conozco un lenguaje de programación que soporta esta estructura de control directamente. Es Oberon-07 (PDF, 70 KB). Y es compatible con "Dijkstra's Loop" en tu forma de declaración while. Echa un vistazo a la sección 9.6. Mientras que las declaraciones en el PDF anterior.
PD: Esta es una copia de mi respuesta SO .
fuente
Expresiones de estilo de icono con retroceso incorporado.
Python obtiene muchos de los beneficios del generador de íconos, y en general funciona mejor, IMO. Y, en principio, el retroceso fue solo una especie de lanzamiento de excepción, pero fue la simplicidad de las expresiones el equivalente aproximado de ...
para manejar casos de falla como la división por cero.
Donde Icon se volvió loco: sin operadores de comparación de retorno booleano. Las comparaciones siempre tuvieron éxito o provocaron un retroceso, y hubo otro problema semántico que ahora estoy tratando desesperadamente de recordar que ... bueno, digamos que probablemente sea más reprimido que olvidado.
Siempre pensé que deberían tener una
if
expresión sin otra parte (if (condition, success-value)
tipo de cosa, retroceder si la condición vuelve falsa) y descartar las extrañas comparaciones.EDITAR Recuerdo, obviamente obvio. Una comparación con dos argumentos tiene éxito o falla: no calcula un nuevo valor para devolver. Por eso, cuando tiene éxito, lo que hace que vuelva? Respuesta: uno de los argumentos. Pero si escribes
a > b
, ¿cuál es el argumento lógico para volver,a
ob
? ¿Y qué pasa si escribes en sub < a
lugar? Yo creo que siempre se devuelve el argumento de la derecha, que tiene tanto sentido como cualquier cosa, pero todavía por lo general parecía que el argumento mal a mí.fuente
Esta es solo una idea general y una sintaxis:
TAMBIÉN la condición siempre se evalúa. ELSE funciona como de costumbre.
Funciona para el caso también. Probablemente sea una buena forma de eliminar la declaración de ruptura:
se puede leer como:
No sé si esto es útil o simple de leer, pero es un ejemplo.
fuente
Continuar Pasando Estilo viene a la mente. Entonces, por supuesto, también le gustaría tener la Optimización de llamadas de cola .
fuente
goto return ...;
declaración, haciendo explícita la intención de llamar a la cola, por lo que si el compilador no puede hacerlo iterativo, es un error.Ramificación de subprocesos sin problemas, tiene una sintaxis como una función, pero se ejecuta en un subproceso separado y no puede acceder a los datos que inicialmente no se le han pasado.
Cuando se llama a una rama, inmediatamente devolverá un identificador.
El identificador se puede usar para verificar si la tarea está hecha.
Si se solicita el resultado antes de que se complete la ejecución, el hilo principal simplemente esperará.
Esto no cubriría los escenarios de subprocesos múltiples más avanzados, sino que proporcionaría una forma fácilmente accesible de comenzar a utilizar múltiples núcleos.
fuente
handle.finished()
prueba, perospawn
ysync
son todo lo que necesita para el 90% de las tareas de programación paralela.Los bloques FIRST y THEN se ejecutan si alguno de los 3 condicionales se evalúa como verdadero El primer bloque se ejecuta antes del bloque condicional y ENTONCES se ejecuta después de que se haya ejecutado el bloque condicional.
ELSE escritura condicional o final después de la declaración FIRST y THEN son independientes de estos bloques.
Se puede leer como:
Estas funciones son solo una forma de leer. No crearían alcance. Es más como un gosub / return de Basic.
Utilidad y legibilidad como tema de discusión.
fuente
A veces me encuentro escribiendo un bucle que necesita hacer algo diferente durante la primera iteración. Por ejemplo, mostrar etiquetas <th> en lugar de etiquetas <td>.
Manejo esta situación con una bandera booleana. Algo como esto:
Parece una tontería comprobar el valor de
first
cada iteración cuando será falso la mayor parte del tiempo.Me gustaría tener una opción de bucle para especificar un cuerpo de bucle diferente en la primera iteración. No habría necesidad de una variable separada. El código compilado tampoco necesitaría uno, porque el código generado tendría dos cuerpos, uno para la primera iteración y otro para el resto.
fuente
print(out, first "<th>" then "<td>")
if (!first) gimme-a-comma ();
, pero casi lo mismo. Sin embargo, tendría una objeción: si lo envuelve adecuadamente termina con cosas como el método de combinación de cadenas de Python, sin embargo, a menudo necesita el patrón básico, el bucle subyacente no necesita reescribirse con tanta frecuencia.if (!first)
, pero los micro optimizadores pueden plantear objeciones de predicción de rama.if (!first)
y dejar que un compilador de optimización decida si el cuerpo del bucle es lo suficientemente pequeño como para desenrollarlo y deshacerse de élfirst
es una ganancia neta.[copiado de mi propia respuesta en stackoverflow]
ignoring
- Para ignorar las excepciones que ocurren en un determinado bloque de código.Con una construcción de control ignorante, puede escribirla de manera más concisa y más legible como:
[Scala proporciona esto (y muchas otras construcciones de control de manejo de excepciones) en su biblioteca estándar, en el paquete util.control. ]
fuente
try..catch
bloque vacío es una cosa; te obliga a reconocer el error e ignorarlo deliberadamente; Si bien arrojar fragmentos de código bajo una omisión global puede generar problemas cuando se lanzan esas excepciones, así como generar malos hábitos de programación.try
bloque, excepto que enumera las excepciones que detecta e ignora por adelantado, en lugar de más adelante. Eso incluso podría ser una ventaja de legibilidad, por ejemplo, dejarle saber al lector que un archivo faltante no es un error incluso antes de leer la llamada abierta.En lugar de:
Hazlo en Python, o ahora también en C #:
Scala tiene muchas características nuevas.
Finalmente, lenguajes como Clojure pueden ampliarse para proporcionar la funcionalidad adicional.
fuente
Tengo dos ideas
A menudo encuentro que me estoy repitiendo en
catch
bloques. Esto puede ser de alguna manera ayudado a través de métodos de extracción, pero eso puede causar desorden innecesario si los métodos son muy cortos o no son dignos de un método. Por lo tanto, sería bueno anidarcatch
bloques:En la programación web, a menudo me encuentro haciendo algo como esto (este no es un ejemplo real, así que no analice casos ficticios):
En Javascript (bueno, ECMAScript, y tal vez otros con los que no estoy familiarizado), ya que cualquier valor puede evaluarse como una condición,
||
puede ayudar.Realmente me gusta cómo se ve, y deseo que más idiomas, especialmente algunos en el lado del servidor, tengan soporte para ello. (PHP puede evaluar cualquier cosa como condición, pero convierte toda la expresión condicional en un valor booleano en lugar de preservar el valor. No sé acerca de Python o Ruby.) Podría volverse difícil de manejar después de tres casos más o menos, pero si tiene más de tres casos, también puede tener un mal diseño de software.
fuente
x if c else y
sintaxis de expresión condicional , una razón importante que sucedió fue porque muchas expresiones que usaban esta semántica tenían errores||
y&&
eran sutilmente defectuosas. IIRC, un caso común era un valor (como cero) que era válido para la aplicación que se estaba tratandofalse
, por lo que se descartaba para que se utilizara una reserva no válida. Sin embargo, vea mi respuesta WRT, el lenguaje de programación Icon, que puede tener expresiones comoget1() else get2() else default
.El interruptor generalizado ha dicho anteriormente:
En Haskell:
fuente
En C # me gustaría usar simples
switch () { ... }
, pero extensibles con tales expresiones:Y así. Lo mismo con números u otros tipos (que admite
IComparable
,IConvertible
, ...)Esto podría hacer que mi código sea más lacónico y legible.
fuente
Es una pregunta divertida, como dijo @Macneil.
Mi estructura de control inusual favorita, que descubrí (humilde tos), es la ejecución diferencial .
Tiene ciertos usos. Para mí, el uso abrumador es en la programación de interfaces de usuario, que es una instancia del problema más general de mantener datos redundantes en correspondencia. Por un lado, hay datos de aplicaciones y, por otro, hay controles de interfaz de usuario que deben mantenerse de acuerdo. Esto suena como "vinculante", pero en realidad hay mucho más.
Por lo general, lo implemento por macros en C o C ++. En C # tengo que hacerlo mediante declaraciones de expansión manual. Eso es un dolor, pero funciona.
Una vez que lo implementé en términos de macros Lisp, y luego estaba muy limpio. No requirió cuidado por parte del programador. Podría haber hecho lo mismo en cualquier otro lenguaje estructurado si me hubiera tomado la molestia de escribir un analizador completo y luego generar todas las cosas correctas. Ese es un gran proyecto, y no lo he hecho.
fuente
Las estructuras de control "tradicionales"
for
tienen que ver con el control del trabajador, manteniéndolo subordinado a las ideologías corruptas de la élite capitalista gobernante. Es por eso que uso estructuras de control alternativas como en suph0r
lugar. Es comofor
, pero más radical: no te sorprenderáph0r
usar traje y corbata, escupiendo algunas BS corporativas.ph0r
lo mantiene real, hombre.¡Luchar contra el poder!
fuente
for
Bucle más simplefuente