stringtranslate.com

Programación basada en flujo

En programación informática , la programación basada en flujo ( FBP ) es un paradigma de programación que define las aplicaciones como redes de procesos de caja negra , que intercambian datos a través de conexiones predefinidas mediante el paso de mensajes , donde las conexiones se especifican externamente a los procesos. Estos procesos de caja negra se pueden reconectar infinitamente para formar diferentes aplicaciones sin tener que cambiarlas internamente. Por lo tanto, la FBP está naturalmente orientada a componentes .

FBP es una forma particular de programación de flujo de datos basada en buffers limitados, paquetes de información con duraciones definidas, puertos nombrados y definición separada de conexiones.

Introducción

La programación basada en flujo define las aplicaciones utilizando la metáfora de una "fábrica de datos". Considera a una aplicación no como un proceso único y secuencial que comienza en un punto en el tiempo y luego hace una cosa a la vez hasta que termina, sino como una red de procesos asincrónicos que se comunican por medio de flujos de fragmentos de datos estructurados, llamados "paquetes de información" (IP). En esta perspectiva, el enfoque se centra en los datos de la aplicación y las transformaciones que se les aplican para producir los resultados deseados. La red se define externamente a los procesos, como una lista de conexiones que es interpretada por un software, generalmente llamado "programador".

Los procesos se comunican por medio de conexiones de capacidad fija. Una conexión se conecta a un proceso por medio de un puerto , que tiene un nombre acordado entre el código del proceso y la definición de red. Más de un proceso puede ejecutar el mismo fragmento de código. En cualquier momento, una IP dada solo puede ser "propiedad" de un solo proceso, o estar en tránsito entre dos procesos. Los puertos pueden ser simples o de tipo matriz, como se usa, por ejemplo, para el puerto de entrada del componente Collate que se describe a continuación. Es la combinación de puertos con procesos asincrónicos lo que permite que muchas funciones primitivas de procesamiento de datos de larga duración, como Ordenar, Fusionar, Resumir, etc., se admitan en forma de cajas negras de software .

Debido a que los procesos FBP pueden continuar ejecutándose mientras tengan datos con los que trabajar y algún lugar donde colocar su salida, las aplicaciones FBP generalmente se ejecutan en menos tiempo que los programas convencionales y hacen un uso óptimo de todos los procesadores de una máquina, sin necesidad de una programación especial para lograrlo. [1]

La definición de red suele ser diagramática y se convierte en una lista de conexiones en algún lenguaje o notación de nivel inferior. FBP suele ser un lenguaje de programación visual en este nivel. Las definiciones de red más complejas tienen una estructura jerárquica, que se construye a partir de subredes con conexiones "pegajosas". Muchos otros lenguajes/tiempos de ejecución basados ​​en flujo se construyen en torno a lenguajes de programación más tradicionales; el ejemplo más notable [ cita requerida ] es RaftLib , que utiliza operadores similares a iostream de C++ para especificar el gráfico de flujo.

FBP tiene mucho en común con el lenguaje Linda [2] en el sentido de que es, en la terminología de Gelernter y Carriero, un "lenguaje de coordinación": [3] es esencialmente independiente del lenguaje. De hecho, dado un planificador escrito en un lenguaje de nivel suficientemente bajo, los componentes escritos en diferentes lenguajes se pueden vincular entre sí en una única red. FBP, por tanto, se presta al concepto de lenguajes específicos de dominio o "minilenguajes".

FBP exhibe "acoplamiento de datos", descrito en el artículo sobre acoplamiento como el tipo más flexible de acoplamiento entre componentes. El concepto de acoplamiento flexible está a su vez relacionado con el de las arquitecturas orientadas a servicios , y FBP cumple con varios de los criterios para este tipo de arquitectura, aunque a un nivel más detallado que la mayoría de los ejemplos de esta arquitectura.

FBP promueve un estilo de especificaciones funcional de alto nivel que simplifica el razonamiento sobre el comportamiento del sistema. Un ejemplo de esto es el modelo de flujo de datos distribuidos para especificar y analizar de manera constructiva la semántica de protocolos distribuidos de múltiples partes.

Historia

La programación basada en flujo fue inventada por J. Paul Morrison a principios de la década de 1970, e inicialmente implementada en software para un banco canadiense. [4] FBP en sus inicios estuvo fuertemente influenciada por algunos lenguajes de simulación de IBM de la época, en particular GPSS , pero sus raíces se remontan al artículo seminal de Conway sobre lo que él llamó corrutinas . [5]

FBP ha sufrido varios cambios de nombre a lo largo de los años: la implementación original se llamó AMPS (Advanced Modular Processing System). Una gran aplicación en Canadá se puso en marcha en 1975 y, a partir de 2013, ha estado en uso de producción continua, ejecutándose a diario, durante casi 40 años. Debido a que IBM consideró que las ideas detrás de FBP "se parecían demasiado a una ley de la naturaleza" para ser patentables, en su lugar puso los conceptos básicos de FBP en el dominio público, por medio de un Boletín de divulgación técnica , "Data Responsive Modular, Interleaved Task Programming System", [6] en 1971. [4] Un artículo que describe sus conceptos y experiencia de uso se publicó en 1978 en IBM Research IBM Systems Journal bajo el nombre DSLM. [7] Una segunda implementación se realizó como un proyecto conjunto de IBM Canadá e IBM Japón, bajo el nombre "Data Flow Development Manager" (DFDM), y se comercializó brevemente en Japón a fines de los años 80 con el nombre "Data Flow Programming Manager".

Generalmente, en IBM se hacía referencia a los conceptos como "Flujo de datos", pero se consideró que este término era demasiado general y finalmente se adoptó el nombre "Programación basada en flujo".

Desde principios de los años 80 hasta 1993, J. Paul Morrison y el arquitecto de IBM Wayne Stevens refinaron y promovieron los conceptos detrás de FBP. Stevens escribió varios artículos que describen y respaldan el concepto de FBP, e incluyó material sobre él en varios de sus libros. [8] [9] [ fuente no primaria necesaria ] [10] [ fuente no primaria necesaria ] . En 1994, Morrison publicó un libro que describe FBP y proporciona evidencia empírica de que FBP condujo a tiempos de desarrollo reducidos. [11]

Conceptos

El siguiente diagrama muestra las entidades principales de un diagrama FBP (aparte de los paquetes de información). Un diagrama de este tipo se puede convertir directamente en una lista de conexiones, que luego puede ser ejecutada por un motor adecuado (software o hardware).

Diagrama FBP simple

A, B y C son procesos que ejecutan componentes de código. O1, O2 y las dos IN son puertos que conectan las conexiones M y N a sus respectivos procesos. Se permite que los procesos B y C ejecuten el mismo código, por lo que cada proceso debe tener su propio conjunto de almacenamiento de trabajo, bloques de control, etc. Independientemente de si comparten código o no, B y C tienen la libertad de usar los mismos nombres de puerto, ya que los nombres de puerto solo tienen significado dentro de los componentes que los referencian (y a nivel de red, por supuesto).

M y N son lo que a menudo se denomina " buffers limitados " y tienen una capacidad fija en términos de la cantidad de direcciones IP que pueden contener en cualquier momento.

El concepto de puertos es lo que permite que el mismo componente se utilice en más de un lugar de la red. En combinación con una capacidad de parametrización, denominada Paquetes de Información Inicial (IIP), los puertos proporcionan a FBP una capacidad de reutilización de componentes, lo que convierte a FBP en una arquitectura basada en componentes . FBP exhibe así lo que Raoul de Campo y Nate Edwards de IBM Research han denominado modularidad configurable .

Los paquetes de información o IP se asignan en lo que podría llamarse "espacio IP" (así como las tuplas de Linda se asignan en "espacio de tuplas"), y tienen una vida útil bien definida hasta que se eliminan y se recupera su espacio; en FBP, esto debe ser una acción explícita por parte de un proceso propietario. Los IP que viajan a través de una conexión dada (en realidad, son sus "identificadores" los que viajan) constituyen un "flujo", que se genera y se consume de forma asincrónica; este concepto tiene similitudes con el concepto de conexiones perezosas descrito en el artículo de 1976 de Friedman y Wise. [12]

Las direcciones IP suelen ser fragmentos estructurados de datos; sin embargo, algunas direcciones IP pueden no contener ningún dato real, sino que se utilizan simplemente como señales. Un ejemplo de esto son las "direcciones IP entre paréntesis", que se pueden utilizar para agrupar direcciones IP de datos en patrones secuenciales dentro de un flujo, denominados "subflujos". Los subflujos pueden, a su vez, estar anidados. Las direcciones IP también se pueden encadenar para formar "árboles de direcciones IP", que viajan a través de la red como objetos individuales.

El sistema de conexiones y procesos descrito anteriormente se puede "ramificar" hasta alcanzar cualquier tamaño. Durante el desarrollo de una aplicación, se pueden añadir procesos de monitorización entre pares de procesos, se pueden "explotar" los procesos en subredes o se pueden sustituir las simulaciones de procesos por la lógica del proceso real. Por tanto, FBP se presta al prototipado rápido .

En realidad, se trata de una imagen de procesamiento de datos que se asemeja a una cadena de montaje : las direcciones IP que viajan a través de una red de procesos pueden considerarse como aparatos que viajan de una estación a otra en una cadena de montaje. Las "máquinas" pueden reconectarse fácilmente, desconectarse para su reparación, reemplazarse, etc. Curiosamente, esta imagen es muy similar a la de los equipos de registro de unidades que se utilizaban para procesar datos antes de la era de las computadoras, salvo que las barajas de cartas debían transportarse a mano de una máquina a otra.

Las implementaciones de FBP pueden ser preemptivas o no preemptivas: las implementaciones anteriores tendían a ser no preemptivas (mainframe y lenguaje C), mientras que la última implementación de Java (ver a continuación) usa la clase Java Thread y es preemptiva.

Ejemplos

El problema del telegrama

Los componentes FBP suelen formar pares complementarios. Este ejemplo utiliza dos de estos pares. El problema descrito parece muy simple tal como se describe en palabras, pero de hecho es sorprendentemente difícil de resolver utilizando la lógica procedimental convencional. La tarea, llamada el "problema del telegrama", descrita originalmente por Peter Naur , consiste en escribir un programa que acepte líneas de texto y genere líneas de salida que contengan tantas palabras como sea posible, donde el número de caracteres en cada línea no exceda una cierta longitud. Las palabras no se pueden dividir y asumimos que ninguna palabra es más larga que el tamaño de las líneas de salida. Esto es análogo al problema de ajuste de palabras en los editores de texto. [13]

En la lógica convencional, el programador descubre rápidamente que ni las estructuras de entrada ni las de salida pueden utilizarse para controlar la jerarquía de llamadas del flujo de control . En cambio, en FBP, la propia descripción del problema sugiere una solución:

Esta es la solución más natural en FBP (no existe una única solución "correcta" en FBP, pero esta parece una solución natural):

El problema del telegrama de Peter Naur

donde DC y RC significan "DeCompose" y "ReCompose", respectivamente.

Como se mencionó anteriormente, los paquetes de información inicial (IIP) se pueden utilizar para especificar información paramétrica, como la longitud de registro de salida deseada (requerida por los dos componentes más a la derecha) o los nombres de archivo. Los IIP son fragmentos de datos asociados con un puerto en la definición de red que se convierten en direcciones IP "normales" cuando se emite una "recepción" para el puerto correspondiente.

Actualización por lotes

Este tipo de programa implica pasar un archivo de "detalles" (cambios, añadidos y borrados) a un "archivo maestro" y producir (al menos) un archivo maestro actualizado y uno o más informes. Los programas de actualización son generalmente bastante difíciles de codificar utilizando código procedimental sincrónico, ya que dos (a veces más) flujos de entrada deben mantenerse sincronizados, aunque puede haber maestros sin detalles correspondientes, o viceversa.

Estructura de "actualización por lotes" canónica

En FBP, un componente reutilizable (Collate), basado en la idea de registro de unidad de un Collator, hace que escribir este tipo de aplicación sea mucho más fácil, ya que Collate fusiona los dos flujos e inserta direcciones IP entre corchetes para indicar los niveles de agrupación, lo que simplifica significativamente la lógica descendente. Supongamos que un flujo ("masters" en este caso) consta de direcciones IP con valores de clave de 1, 2 y 3, y las direcciones IP del segundo flujo ("details") tienen valores de clave de 11, 12, 21, 31, 32, 33 y 41, donde el primer dígito corresponde a los valores de clave de master. Al utilizar caracteres entre corchetes para representar direcciones IP "entre corchetes", el flujo de salida cotejado será el siguiente:

( m1 d11 d12 ) ( m2 d21 ) ( m3 d31 d32 d33 ) (d41)

Como no había ningún master con valor 4, el último grupo consta de un solo detalle (más corchetes).

La estructura del flujo anterior se puede describir sucintamente utilizando una notación similar a BNF como

{ ( [m] d* ) }*

Collate es una caja negra reutilizable que solo necesita saber dónde están los campos de control en sus direcciones IP entrantes (aunque esto no es estrictamente necesario, ya que se pueden insertar procesos de transformación en sentido ascendente para colocar los campos de control en ubicaciones estándar) y, de hecho, se puede generalizar a cualquier cantidad de flujos de entrada y a cualquier profundidad de anidamiento de corchetes. Collate utiliza un puerto de tipo matriz para la entrada, lo que permite una cantidad variable de flujos de entrada.

Procesos de multiplexación

La programación basada en flujos permite la multiplexación de procesos de una forma muy natural. Dado que los componentes son de solo lectura, cualquier número de instancias de un componente determinado ("procesos") pueden ejecutarse de forma asincrónica entre sí.

Ejemplo de multiplexación

Cuando las computadoras tenían un solo procesador, esto era útil cuando se realizaban muchas operaciones de E/S; ahora que las máquinas suelen tener varios procesadores, esto está empezando a ser útil también cuando los procesos hacen un uso intensivo de la CPU. El diagrama de esta sección muestra un solo proceso "Load Balancer" que distribuye datos entre tres procesos, denominados S1, S2 y S3, respectivamente, que son instancias de un solo componente, que a su vez alimentan un solo proceso por orden de llegada.

Red interactiva sencilla

Esquema de aplicación interactiva general

En este esquema general, las solicitudes (transacciones) provenientes de los usuarios ingresan al diagrama en la parte superior izquierda y las respuestas se devuelven en la parte inferior izquierda. Los "back ends" (en el lado derecho) se comunican con sistemas en otros sitios, por ejemplo, mediante CORBA , MQSeries , etc. Las conexiones cruzadas representan solicitudes que no necesitan ir a los back ends o solicitudes que deben pasar por la red más de una vez antes de ser devueltas al usuario.

Como diferentes solicitudes pueden utilizar diferentes back-ends y pueden requerir diferentes cantidades de tiempo para que los back-ends (si se utilizan) las procesen, se deben tomar medidas para relacionar los datos devueltos con las transacciones solicitantes apropiadas, por ejemplo, tablas hash o cachés.

El diagrama anterior es esquemático en el sentido de que la aplicación final puede contener muchos más procesos: los procesos pueden insertarse entre otros procesos para administrar cachés, mostrar el tráfico de conexión, monitorear el rendimiento, etc. Además, los bloques en el diagrama pueden representar "subredes": pequeñas redes con una o más conexiones abiertas.

Comparación con otros paradigmas y metodologías

Programación estructurada de Jackson (JSP) y desarrollo de sistemas de Jackson (JSD)

Esta metodología supone que un programa debe estructurarse como una única jerarquía procedimental de subrutinas. Su punto de partida es describir la aplicación como un conjunto de "líneas principales", basadas en las estructuras de datos de entrada y salida. Una de estas "líneas principales" se elige entonces para controlar todo el programa, y ​​las otras deben "invertirse" para convertirlas en subrutinas (de ahí el nombre de "inversión de Jackson"). Esto a veces da como resultado lo que se denomina un "choque", que requiere que el programa se divida en varios programas o corrutinas. Cuando se utiliza FBP, este proceso de inversión no es necesario, ya que cada componente de FBP puede considerarse una "línea principal" independiente.

FBP y JSP comparten el concepto de tratar un programa (o algunos componentes) como un analizador de un flujo de entrada.

En el trabajo posterior de Jackson, Jackson System Development (JSD), las ideas se desarrollaron aún más. [14] [15]

En JSD, el diseño se mantiene como un diseño de red hasta la etapa final de implementación. Luego, el modelo se transforma en un conjunto de procesos secuenciales según el número de procesadores disponibles. Jackson analiza la posibilidad de ejecutar directamente el modelo de red que existe antes de este paso en la sección 1.3 de su libro (cursiva añadida):

La especificación producida al final del paso de sincronización del sistema es, en principio, capaz de ejecutarse directamente. El entorno necesario contendría un procesador para cada proceso, un dispositivo equivalente a un búfer ilimitado para cada flujo de datos y algunos dispositivos de entrada y salida donde el sistema se conecta al mundo real. Por supuesto, un entorno de este tipo podría proporcionarse mediante un software adecuado que se ejecute en una máquina lo suficientemente potente. A veces, dicha ejecución directa de la especificación será posible, e incluso puede ser una opción razonable. [15]

FBP fue reconocido por MA Jackson como un enfoque que sigue su método de "Descomposición del programa en procesos secuenciales que se comunican mediante un mecanismo similar a una corrutina" [16].

Programación aplicativa

WB Ackerman define un lenguaje aplicativo como aquel que realiza todo su procesamiento por medio de operadores aplicados a valores. [17] El primer lenguaje aplicativo conocido fue LISP.

Un componente FBP puede considerarse como una función que transforma sus flujos de entrada en flujos de salida. Estas funciones se combinan para realizar transformaciones más complejas, como se muestra aquí:

Dos funciones que alimentan a una

Si etiquetamos los flujos, como se muestra, con letras minúsculas, entonces el diagrama anterior se puede representar sucintamente de la siguiente manera:

c = G(F(a),F(b));

Así como en la notación funcional F se puede utilizar dos veces porque solo funciona con valores y, por lo tanto, no tiene efectos secundarios, en FBP dos instancias de un componente determinado pueden ejecutarse simultáneamente y, por lo tanto, los componentes de FBP tampoco deben tener efectos secundarios. La notación funcional podría utilizarse claramente para representar al menos una parte de una red FBP.

Surge entonces la pregunta de si los componentes de FBP pueden expresarse mediante notación funcional. WH Burge demostró cómo se pueden desarrollar expresiones de flujo mediante un estilo de programación recursivo y aplicativo, pero este trabajo se realizó en términos de (flujos de) valores atómicos. [18] En FBP, es necesario poder describir y procesar fragmentos de datos estructurados (FBP IP).

Además, la mayoría de los sistemas aplicativos suponen que todos los datos están disponibles en la memoria al mismo tiempo, mientras que las aplicaciones FBP necesitan poder procesar flujos de datos de larga duración mientras siguen utilizando recursos finitos. Friedman y Wise sugirieron una forma de hacer esto añadiendo el concepto de "cons perezosos" al trabajo de Burge. Esto eliminó el requisito de que ambos argumentos de "cons" estén disponibles en el mismo instante de tiempo. "Lazy cons" en realidad no crea un flujo hasta que se realizan ambos argumentos; antes de eso, simplemente registra una "promesa" de hacerlo. Esto permite que un flujo se realice dinámicamente desde el principio, pero con un final no realizado. El final del flujo permanece sin realizarse hasta el final del proceso, mientras que el comienzo es una secuencia de elementos que se alarga cada vez más.

Linda

Muchos de los conceptos de FBP parecen haber sido descubiertos de forma independiente en diferentes sistemas a lo largo de los años. Linda, mencionada anteriormente, es uno de ellos. La diferencia entre las dos técnicas se ilustra con la técnica de equilibrio de carga de la "escuela de pirañas" de Linda : en FBP, esto requiere un componente "equilibrador de carga" adicional que dirige las solicitudes al componente de una lista que tiene la menor cantidad de direcciones IP en espera de ser procesadas. Claramente, FBP y Linda están estrechamente relacionados, y uno podría usarse fácilmente para simular el otro.

Programación orientada a objetos

Un objeto en programación orientada a objetos puede describirse como una unidad semiautónoma que comprende tanto información como comportamiento. Los objetos se comunican por medio de "llamadas a métodos", que son esencialmente llamadas a subrutinas, realizadas indirectamente a través de la clase a la que pertenece el objeto receptor. Solo se puede acceder a los datos internos del objeto por medio de llamadas a métodos, por lo que se trata de una forma de ocultamiento de información o "encapsulación". Sin embargo, la encapsulación es anterior a la programación orientada a objetos ( David Parnas escribió uno de los artículos fundamentales sobre ella a principios de los años 70 [19] ) y es un concepto básico en informática. La encapsulación es la esencia misma de un componente FBP, que puede considerarse como una caja negra que realiza alguna conversión de sus datos de entrada en sus datos de salida. En FBP, parte de la especificación de un componente son los formatos de datos y las estructuras de flujo que puede aceptar y los que generará. Esto constituye una forma de diseño por contrato . Además, solo el proceso propietario actual puede acceder directamente a los datos de una IP. La encapsulación también se puede implementar a nivel de red, haciendo que los procesos externos protejan a los internos.

Un artículo de C. Ellis y S. Gibbs distingue entre objetos activos y objetos pasivos. [20] Los objetos pasivos comprenden información y comportamiento, como se indicó anteriormente, pero no pueden determinar el momento de este comportamiento. Los objetos activos, por otro lado, sí pueden hacerlo. En su artículo, Ellis y Gibbs afirman que los objetos activos tienen mucho más potencial para el desarrollo de sistemas mantenibles que los objetos pasivos. Una aplicación FBP puede verse como una combinación de estos dos tipos de objetos, donde los procesos FBP corresponderían a objetos activos, mientras que los IP corresponderían a objetos pasivos.

Modelo de actor

FBP considera al actor de Carl Hewitt como un proceso asincrónico con dos puertos: uno para mensajes de entrada y otro para señales de control. El propio actor emite una señal de control después de cada ronda de ejecución. El objetivo de esta señal es evitar la ejecución paralela del cuerpo del actor y, de esta forma, permitir el acceso a los campos del objeto actor sin sincronización.

Véase también

Referencias

  1. ^ "Programación basada en flujo".
  2. ^ Carriero, Nicholas; Gelernter, David (1989). "Linda en contexto". Comunicaciones de la ACM . 32 (4): 444–458. doi : 10.1145/63334.63337 . S2CID  5900105.
  3. ^ Gelernter, David; Carriero, Nicholas (1992). "Lenguajes de coordinación y su importancia". Comunicaciones de la ACM . 35 (2): 97–107. doi :10.1145/129630.129635. S2CID  7748555.
  4. ^ por Gabe Stein (agosto de 2013). "Cómo un método de codificación arcano del software bancario de los años 70 podría salvar la cordura de los desarrolladores web de todo el mundo" . Consultado el 24 de enero de 2016 .
  5. ^ Conway, Melvin E. (1963). "Diseño de un compilador de diagrama de transición separable". Comunicaciones de la ACM . 6 (7): 396–408. doi : 10.1145/366663.366704 . S2CID  10559786.
  6. ^ J. Paul Morrison, Sistema de programación de tareas intercaladas modulares y sensibles a los datos, Boletín de divulgación técnica de IBM, vol. 13, n.º 8, 2425-2426, enero de 1971
  7. ^ Morrison, JP (1978). "Mecanismo de enlace de flujo de datos". IBM Systems Journal . 17 (4): 383–408. doi :10.1147/sj.174.0383.
  8. ^ Stevens, WP (1982). "Cómo el flujo de datos puede mejorar la productividad del desarrollo de aplicaciones". IBM Systems Journal . 21 (2): 162–178. doi :10.1147/sj.212.0162.
  9. ^ WP Stevens, Uso del flujo de datos para el desarrollo de aplicaciones , Byte, junio de 1985
  10. ^ WP Stevens, Diseño de software: conceptos y métodos , Serie de ingeniería de software práctica, Ed. Allen Macro, Prentice Hall, 1990, ISBN 0-13-820242-7 
  11. ^ Johnston, Wesley M.; Hanna, JR Paul; Millar, Richard J. (2004). "Avances en lenguajes de programación de flujo de datos". Encuestas de computación de ACM . 36 (1): 1–34. CiteSeerX 10.1.1.99.7265 . doi :10.1145/1013208.1013209. S2CID  5257722. 
  12. ^ DP Friedman y DS Wise, CONS no debería evaluar sus argumentos, Automata, Languages ​​and Programming, Edinburgh University Press, Edimburgo, 1976
  13. ^ "El problema del Telegram de Peter Naur". Archivado desde el original el 6 de septiembre de 2014. Consultado el 6 de septiembre de 2014 .
  14. ^ "Programación" de MA Jackson, publicado en Proceedings of Workshop on Software in High-Energy Physics, páginas 1-12 , CERN, Ginebra, 4-6 de octubre de 1982
  15. ^ ab "Un método de desarrollo de sistemas Archivado el 6 de febrero de 2012 en Wayback Machine " por MA Jackson, publicado en Herramientas y nociones para la construcción de programas: un curso avanzado , Cambridge University Press, 1982
  16. ^ "JSP en perspectiva" Michael Jackson; JSP en perspectiva; en Pioneros del software: contribuciones a la ingeniería del software; Manfred Broy, Ernst Denert eds; Springer, 2002
  17. ^ WB Ackerman, Lenguajes de flujo de datos , Actas de la Conferencia Nacional de Computación, págs. 1087-1095, 1979
  18. ^ WH Burge, Técnicas de programación recursiva , Addison-Wesley, Reading, MA, 1975
  19. ^ Parnas, DL (1972). "Sobre los criterios que se deben utilizar en la descomposición de sistemas en módulos". Comunicaciones de la ACM . 15 (12): 1053–1058. doi : 10.1145/361598.361623 . S2CID  53856438.
  20. ^ C. Ellis y S. Gibbs, Objetos activos: realidades y posibilidades , en Conceptos, bases de datos y aplicaciones orientadas a objetos , eds. W. Kim y FH Lochovsky, ACM Press, Addison-Wesley, 1989

Enlaces externos

Véase también