¿Para qué problemas son adecuados y no adecuados los lenguajes orientados a pila?

7

Programación orientada a la pila es un paradigma muy poco utilizado (bueno, PostScript se usa debajo del capó un poco aquí y allá). Teniendo esto en cuenta, ¿en qué problemas son buenos los lenguajes orientados a la pila? ¿Qué harían mejor que [paradigma]? Además, ¿para qué problemas son una mala elección?

¿Es la programación orientada a la pila solo un paradigma de nicho?

    
pregunta Anto 10.04.2011 - 21:55

4 respuestas

15

El principal problema con los lenguajes de programación orientados a la pila es que conceptualmente son muy difíciles de entender para los humanos. La ventaja es que son muy fáciles para que las computadoras evalúen y generen .

Es por eso que fue elegido para PostScript. No hace mucho tiempo que las impresoras solo tenían una cantidad muy pequeña de memoria y CPU con muy poca potencia. Por lo tanto, al darles programas en un lenguaje que era fácil de interpretar y también fácil de generar, no necesitabas una súper computadora dentro de tu impresora para evaluar.

También tenga en cuenta que muchos idiomas de hoy, aunque no están orientados a la pila en sí mismos, en realidad se compilan en un código de bytes orientado a la pila (piense en Java y .NET). Nuevamente, la razón es que el procesamiento orientado a la pila es muy fácil de razonar para una computadora.

    
respondido por el Dean Harding 10.04.2011 - 22:17
6

Thorbjørn ya se refirió a la compilación: si recuerdo correctamente, el código de bytes de Java es un ejemplo de un lenguaje orientado a la pila. Aunque esto no es universal. LLVM usa una cosa de "asignación única estática" que ciertamente tiene una pila, pero en la cual los accesos de variables locales y la evaluación de expresiones usan una tipo de registro virtual de una vez, entonces, inmutable. Para datos mutables, estas cosas básicamente contienen un puntero inmutable.

De todos modos, un lenguaje orientado a la pila puede hacer cualquier cosa que parezca Lisp o ALGOL , como puede hacer el lenguaje, computacionalmente hablando. La pila puede incluso tener metadatos implícitos, haciendo cosas aproximadamente equivalentes a la inferencia de tipo en ML , por ejemplo: evaluado en tiempo de compilación, sin hacer un solo empuje o pop en tiempo de ejecución.

El problema real es la legibilidad, por lo que la pregunta es cuál de estos encuentra más legible ...

a * b + c * d
(+ (* a b) (* c d))
a b * c d * +

En principio, el prefijo de tipo Lisp podría hacerse sin paréntesis, pero tendría que usar un número fijo de argumentos por operador (como postfix e infijo) para hacerlo. Creo que hay algo de verdad en la vieja broma de "Muchos paréntesis de manera estúpida", pero eso podría evitarse mientras se sigue haciendo el primer pedido del operador. En otras palabras, puedes escribir un compilador que acepte ...

+ * a b * c d

En lo que es más legible, eso es claramente discutible. Infix es más familiar para los novatos, pero no se necesita mucho para sentirse cómodo con cualquiera de esos formularios.

Personalmente, ni siquiera estoy convencido de que esto cuente como un paradigma. Es solo una notación, con poco o ningún impacto semántico. Por ejemplo, las tres formas podrían manejarse usando una gramática Yacc : las tres usan exactamente la misma AST , por lo que el análisis semántico y la generación de código ni siquiera necesitan saber si la sintaxis parece estar" orientada a la pila ".

EDIT

Vaya, creo que el punto básico está arriba, pero creo que debería declarar explícitamente mi respuesta. Que es básicamente que, en mi opinión, no hay ningún problema en particular que favorezca ninguna de esas notaciones. Las personas pueden favorecer a uno u otro, pero eso es algo diferente.

Sin embargo, lo que los programadores de Lisp señalarán es que la metaprogramación funciona bastante bien con una notación similar a Lisp. Sin embargo, eso es más sobre los paréntesis que donde aparece el operador: una variante de Forth que permitió ...

(1 2 3 4 +)

... sería igual de bueno. De cualquier manera, el beneficio es la notación simple para manipular el uso del código, la misma razón por la que los lenguajes intermedios orientados a la pila (códigos de bytes, etc.) son populares. Aunque podría decirse que manipular el formulario AST agnóstico a los pedidos también se puede hacer con bastante facilidad, eso es algo que hace la comparación de patrones en Haskell y ML.

EDIT - Una aclaración ...

Usar un formulario basado en postfix / stack significa solo eso. Por ejemplo, no implica ningún cambio de orden de argumento. Los siguientes ejemplos pueden ser todos equivalentes, excepto la sintaxis utilizada para expresarlos ...

(< 1 2)
(1 < 2)
(1 2 <)

Nota: no es necesario cambiar el orden del 1 y el 2 simplemente porque el operador es postfix

(if (< a b) (handle a_smaller) (handle b_smaller_or_equal))

((a b <) (a_smaller handle) (b_smaller_or_equal handle) if)
((a_smaller handle) (b_smaller_or_equal handle) (a b <) if)

Quizás quieras mantener la condición cerca de if , quizás no. Cualquiera de las dos está bien.

Forth no expresa un if de ninguna de estas formas, pero no hay ninguna razón por la que un lenguaje orientado a postfix / stack no pueda hacerlo. Forth solo permitía enteros en su pila (al menos originalmente), pero Lisp permitir que se pasen expresiones de efecto secundario como parámetros no tiene nada que ver con ser prefijo en lugar de postfix. Un lenguaje postfix también podría permitir que el código se pase como argumentos (es decir, empujado en la pila) también.

    
respondido por el Steve314 10.04.2011 - 22:48
2

He usado algunos lenguajes orientados a la pila a lo largo de los años.

En la universidad, me divertí mucho confundiendo a los administradores de sistemas con los diminutos programas PostScript que parecían tomar una cantidad ordenada Tiempo para renderizar solo una página de salida. Sí, la impresora láser a la que tuvimos acceso tenía más poder de punto flotante que las mini computadoras en las que nos dieron las cuentas, por lo que fue genial para hacer mandelbrots .

También trabajé con transputers . Estos eran procesadores que estaban altamente optimizados para el rendimiento por transistor. Cada bit de silicio necesario para tirar de su peso, por lo que tenía un conjunto de instrucciones Huffman codificado (las instrucciones más comunes se codificaron en un solo byte) y en lugar de tener el conjunto de registro tradicional, tenía un par de pilas. Una pila era de baja prioridad, la otra alta, lo que significaba que tenía un tiempo de cambio de contexto (proceso de baja prioridad a alta) medido en microsegundos en lugar de milisegundos, ideal para una rápida respuesta de interrupción en los controladores de robot que creamos.

También trabajé en algunos sistemas robóticos que usaban procesadores Forth que se ejecutaban en Forth casi como una máquina código. Recuerdo que compraríamos el doble de CPU que necesitábamos y las agruparíamos de acuerdo con el rendimiento, seleccionando la mejor mitad para poner en los sistemas, eso es porque era más barato comprar varios chips sin calificación que comprar un solo chip con la velocidad Los necesitábamos para correr. * 8 ')

    
respondido por el Mark Booth 12.04.2011 - 01:49
0

Forth está casi muerto, creo. Hay J, sin embargo, no sé si tiene una influencia notable. PostScript no se usa realmente para la programación por humanos, ¿verdad? Por lo que diría, los lenguajes orientados a pila virtualmente ya no existen.

Por lo que veo, son buenos como sustitutos del ensamblador en arquitecturas de hardware orientadas a la pila. Firmware y esas cosas. Pero no estoy seguro de si ese hardware ya existe en el área del procesador de 16 bits posterior.

    
respondido por el Ingo 10.04.2011 - 22:12

Lea otras preguntas en las etiquetas