COMIC
EL LENGUAJE Y COMPILADOR DEL INSTITUTO DE CALCULO EN 1965

Wilfred O. Durán,  Universidad de Carabobo, Venezuela – w.duran@cantv.net 
Cristina Zoltan,  Universitat Politècnica de Catalunya, España – zoltan@ldc.usb.ve 
Clarisa D. Cortés,  Ministerio de Educación, Argentina – asere@fibertel.com.ar 
Liana S. Lew,  ANPCyT, MINCYT, Argentina – liana.lew@gmail.com 
Noemí S. García,  ANSES, Argentina – mimiburgos@gmail.com 

Resumen 

Los lenguajes de programación han sido la vía para simplificar el uso de  las computadoras, permitiendo expresar soluciones automatizables a problemas cada vez más complejos.
En este trabajo se describe el origen, la concepción, el desarrollo y el final de un lenguaje de programación llamado COMIC (COMpilador del Instituto de Cálculo) en la Facultad de Ciencias Exactas y Naturales de la Universidad de Buenos Aires, Argentina.
 
COMIC nace en 1965, en un ambiente de aislamiento que se vivía en el Instituto, como un mecanismo para retener en los centros de Argentina a investigadores que buscaban sacar un mejor provecho de esa novedosa herramienta llamada computadora.

Para el momento, la computadora disponible en el Instituto de Cálculo (la Mercury de Ferranti) tenía un lenguaje y compilador (AUTOCODE) y un lenguaje ensamblador (PIG) y los programadores del resto del mundo usaban Fortran o Cobol para el desarrollo de sus aplicaciones.

COMIC incorpora conceptos novedosos para la época  como identificadores de variables de longitud ilimitada, matrices como tipo predefinido con todas las operaciones: suma, producto, inversa, etc. Procedimientos y funciones definidas por el usuario. El equipo original siguió trabajando para mejorar las facilidades existentes e incorporar nuevas, cuando las condiciones de trabajo en la Facultad, en la Universidad  y en la Argentina toda cambiaron, y COMIC vio su final en la noche de los bastones largos, evento que marcó un antes y un después en la computación en la Argentina.

Introducción

Comenzamos por describir la computadora que teníamos en el Instituto de Cálculo de la Facultad de Ciencias Exactas y Naturales de la Universidad de Buenos en 1965, pero construida y equipada con programas en 1960, y luego nos ubicamos en el estado de la programación en el mundo en esos años, y describimos con detalle el lenguaje de programación que teníamos, AUTOCODE, para documentar los problemas que estaban encontrando los investigadores y programadores usuarios de la nuestra máquina, el modelo Mercury de la empresa Ferranti del Reino Unido. Una vez identificados esos problemas, identificamos la causa de los mismos, la cual era una debilidad fundamental que obligaba a hacer cambios profundos, causados por una decisión aparentemente trivial en su diseño: una selección desafortunada de la forma de representar una operación aritmética.
Luego describimos con detalle el lenguaje que desarrollamos para sustituir el anterior, resolviendo los problemas originales y agregando nuevas facilidades, surgidas de la adquisición de nuevos equipos (impresora, graficador) y de nuevas necesidades de los usuarios. Y finalizamos contando como se malogró el trabajo por causas ajenas a nuestro control.

Descripción de la computadora Mercury  

Como la describe su fabricante:“Ferranti Ltd. anuncia una nueva Computadora Electrónica Digital de gran tamaño, que será conocida como Mercury. En el diseño de esta computadora el objetivo ha sido producir una máquina la cual, aunque completamente versátil, será utilizada principalmente para desarrollar cálculos de naturaleza científica y técnica.” [1]  Veamos ahora algunos detalles que ubican su “gran tamaño” en su época.

Memoria.  Estaba formada por núcleos de ferrita (un gran avance sobre los tubos Williams usados hasta entonces - un poco más lentos pero de casi nulo mantenimiento) con 4096 palabras cortas de 10 bits (+1 bit de paridad), utilizables como enteros (módulo 1024), como instrucciones de máquina de 20 bits (7 de código de operación + 3 de modificación + 10 dirección o entero), o como punto flotante de 40 bits (10 exponente + 30 mantisa). Como todas las direcciones eran de 10 bits, la unidad de control decidía (según fuese el  código de la instrucción) a qué se aplicaba: 1024 números de 40 bits, 1024 instrucciones de 20 bits, o 1024 números de 10 bits. El tiempo de acceso a una palabra de 10 bits era de 10µseg.  Se dispuso originalmente de 2 tambores, que luego se extendieron a 4 de 4096x40 bits cada uno. Es decir, hablando en números de 40 bits, la memoria de trabajo tenía una capacidad de 1K y cada tambor 4K. Y estos números eran grandes para su época

Unidad Aritmética.  Estaba formada por un acumulador (A) y siete registros índices (B1-B7). En A se realizan las operaciones las operaciones de suma, resta y multiplicación entre números en punto flotante (suma o resta en 180 µseg y multiplicación en 300 µseg). Como todas las instrucciones son de una dirección, en todas las operaciones está implícita la “dirección” de A. Los registros B1 al B7 se usan como subíndices o como contadores. Este uso de los registros no agrega tiempo a las operaciones en A, pues los últimos 3 bits del código de cada instrucción le dicen a A: haga esta operación con el número que se encuentra en la posición ‘x +el contenido del registro Bi’, B0 siempre contiene 0. B7 es el acumulador para efectuar operaciones entre números enteros de 10 bits. Todas las operaciones con B1-B7 se ejecutan en 60 µseg.

Unidad de control.   Es la parte de la computadora que lee las instrucciones en la memoria, en el orden que estén (salvo que se le ordene alterarlo) y las interpreta. Para poder desempeñar esta tarea la unidad posee un registro de dirección actual, el cual se incrementa en 1 cada vez que lee una instrucción. Las direcciones de instrucciones se refieren a palabras de 20 bits, y por lo tanto la última instrucción posible en un programa –en dirección 1023– sólo está en la mitad de la memoria, con lo cual, si el programador utiliza las direcciones 512 a 1023 para colocar los datos y los resultados de sus cálculos no habrá superposiciones. Las instrucciones para alterar el orden de ejecución cambian la dirección actual, en forma absoluta o condicional, incluso con operaciones con índices en la misma instrucción, en 60 µseg. 
Además de las instrucciones para operar con números, la unidad de control tiene en su repertorio instrucciones para hacer transferencias entre la memoria de trabajo y los tambores, para leer datos de la unidad de entrada, para mandar resultados a la unidad de salida y para comunicarse con el operador mediante un parlante, dos CRTs y tres filas de 10 pequeñas palancas, todo ubicado en la consola del operador.

Unidades de Entrada y Salida.  Estas unidades eran las más sencillas, baratas y de tecnología ya probada: entrada y salida  de datos y programas con cinta de papel perforada de 5 canales. Quién deseaba introducir un programa, o datos para ser usados por el programa, lo perforaba en la cinta de papel con una de varias perforadoras similares a los teletipos ya usadas para enviar telegramas por muchos correos al superarse la era Morse. 
Más adelante se adquirió una impresora de líneas (un cubo ruidoso de aproximadamente 1 metro por arista) que agregaban 1,50 m a los 11,50 m que ya tenía la fila de armarios de vestuario con los circuitos. Luego también se adquirió un graficador (plotter), cuando ya existía el COMIC, y uno de los miembros de nuestro equipo (CZ) escribió las funciones necesarias para utilizarlo. El Ing. Paiuk diseñó y construyó un convertidor de tarjetas a cinta perforada para poder usar tarjetas que ya tenían algunos usuarios.

Estado  del arte de los lenguajes de programación

Hasta 1952 las computadoras existentes se programaban en el lenguaje de cada máquina, al principio “cableando” cada instrucción y luego “almacenando” las instrucciones en los diferentes tipos de memorias que fueron siendo inventadas. En esa época comenzó a surgir la idea de que la computadora “escribiese el programa –en lenguaje de máquina– para  hacer los cálculos –escritos en lenguaje matemático– que  yo necesito”.  Existen muchas citas que atestiguan  que esta idea fue hecha realidad en diversos lugares en la década de los sesentas.  Los primeros que obtuvieron resultados concretos fueron Alick E. Glennie, con R. A. “Tony” Brooker como continuador, bajo la dirección del precursor Alan M. Turing–quienes fijaron el rumbo para la programación en Inglaterra– y  John W. Backus –quién fijó el rumbo para la IBM. 
Alick E. Glennie (1925-2003) [2] programó en 1952 el compilador AUTOCODE para la computadora Mark I construida en 1951 por la Ferranti en colaboración con la Manchester University (MU). Luego colaboró con el equipo de la MU dirigido por Turing (1912-1954), donde Brooker programó las versiones del AUTOCODE para las computadoras siguientes de la Ferranti.
John W. Backus (1924-2007) fue contratado como programador por la IBM en 1950. En 1953 formó un equipo que elaboró y programó el compilador FORTRAN, que fue presentado en 1957. A esta versión siguieron muchas otras, fijando el rumbo de la programación en el mundo occidental y alrededores, dada la presencia de IBM en el planeta, hasta la explosión en el poder de cómputo en los últimos 30 años, y aún empleado en muchos lugares. Antes del FORTRAN, hubo algunos otros ensayos, como el Speedcoding System para la IBM 701, presentado en mayo de 1954. [3]
John McCarthy (1927-)  inventó en 1958 el lenguaje LISP (List Processor), con una sintaxis completamente declarativa,  el cual ha sido empleado como base para múltiples “dialectos” y aún hoy subsiste, siendo el segundo más antiguo (después del FORTRAN) en sobrevivir. 
El lenguaje ALGOL comenzó a diseñarse informalmente por un grupo de investigadores de universidades y empresas europeas, que decidieron darle un carácter más formal a sus aportes y discusiones en una reunión en Copenhagen el 28-2-1959 donde fijaron los miembros del grupo y decidieron publicar boletines con los elementos que fuesen aportados, discutidos y enmendados. [4] Compiladores para este lenguaje fueron escritos para diversas máquinas en uso en Europa, pero su difusión en América fue muy escasa. Otros lenguajes y compiladores fueron apareciendo en esa época, como lo muestran notas e informes. [5]  

Este es el estado que teníamos en 1965 cuando iniciamos nuestro diseño del COMIC. Lamentablemente, no existían la Internet ni Google, así que nuestra información llegaba muy tardía y fragmentada, las revistas especializadas eran pocas y era difícil saber de su existencia, los libros eran escasos y sólo la librería del Centro de Estudiantes de la Facultad nos conseguía algunos. 

El lenguaje y compilador AUTOCODE  

Ya hemos visto el origen y ubicación en el desarrollo de la programación del lenguaje y compilador AUTOCODE;  veamos ahora las características del lenguaje que definen su utilidad y conveniencia de uso.
Los números son de dos tipos: enteros en el rango –512, +511, módulo 1024, y reales (mejor deberíamos decir racionales, pues el número de dígitos no nulos debe ser finito, pero reales se impuso) en el rango –10^76, +10^76, los cuales podían escribirse en punto fijo o en punto flotante.
Las variables que podemos utilizar se denominan: 
  --índices, para valores de tipo entero, empleadas mayormente como subíndices o contadores; son sólo 12, y tienen nombre prefijado, las letras  i j k l m n o p q r s t.
 --variables especiales, para valores de tipo real, sin subíndice, son 29 y tienen nombre prefijado:  a´  b´ ... g´  h´  /  u´  v´ ... y´  z´  /  a  b  ...  g  h   /   u  v  ...  y  z  π.
--variables principales, para valores de tipo real, con subíndice (o sea, elementos de un vector), pueden usar (en total) hasta 480 registros de memoria, y tienen 14 nombres prefijados: a b c d e f g h  u v w x y z π; debe declararse previamente su dimensión: ej.  x>23 reserva 24 registros, x0 a x23.
  --variables auxiliares, para valores de tipo real.  Están localizadas en la llamada “memoria grande” formada por los tambores magnéticos ya descritos;  su número dependía del lugar que ocupasen, del total disponible, otros habitantes de los tambores (había reglas para saber este número).  El “nombre” de cada posición es su dirección en el tambor, comenzando por 0, hasta la última posición disponible.  Los números ubicados en estos registros deben ser traídos a la “memoria actual”, la de ferritos, para operar con ellos. El mayor uso de estas variables era para efectuar operaciones con matrices; había instrucciones que hacían más “transparentes” las mudanzas de memoria para hacer las operaciones, pero el programador debía llevar muy buena cuenta de la ubicación de sus matrices, además de sus dimensiones. 
Las expresiones algebraicas se construyen con las 4 operaciones aritméticas, indicadas en la forma: suma  +, resta  -, división /  y multiplicación por yuxtaposición de los factores. También existen 15 funciones reales y 3 funciones enteras predefinidas que se escriben  φnombre(argumento(s)), cuyos argumentos pueden ser, según el caso individual, expresiones algebraicas, variables, índices. No está permitido mezclar expresiones algebraicas con funciones ni más de una función en las instrucciones aritméticas. 
El álgebra matricial se desarrolla bajo la suposición de que los elementos de todas las matrices están en variables auxiliares, es decir, en los tambores, pues en la memoria actual sólo se dispone de 480 variables principales. El lenguaje provee 23 “funciones” cuyos nombres se identifican con números enteros, desde φ6 hasta φ28, a los cuales siguen, entre paréntesis, dos o más argumentos que identifican variables auxiliares, número de elementos o filas y columnas, involucradas en la operación. Es responsabilidad del programador la escogencia del número de función apropiado y de la fijación de los argumentos, que pueden ser hasta 5: variable auxiliar donde comienza cada operando, número de filas, columnas o elementos, según sea la operación. 
El lenguaje posee un número de instrucciones de control que permiten ejecutar las operaciones en el orden que se desee, incluyendo saltos condicionales y ciclos. Para poder referirse a una instrucción desde otra, cualquier instrucción puede ser precedida por una marca, en la forma  m) instrucción donde m es un entero en el rango 1 a 127.
Dada la estructura de las memorias, el programador debía particionar sus programas en unidades de no más de 832 palabras de 20 bits e iniciar cada una de estas  secciones de programa con la directiva  chapter n  y terminarlas con close, donde n corresponde al sector del tambor donde se almacenaría esta porción de código. Cuando el compilador recibe el chapter 0  lo guarda en el sector 0, da por terminada su tarea y comienza la ejecución del programa por su primera instrucción;  por esto debe ser  leído después de los demás, que pueden ser introducidos en cualquier orden.  La instrucción across m/c  transfiere a la memoria el capítulo c y lo comienza a ejecutar en la instrucción marcada  m) y la  down m/c lo mismo, pero anota la página y la dirección de salida, y si en la página c encuentra la instrucción  up  regresa a la instrucción siguiente de la página de donde partió. 
El lenguaje no permite la programación de bloques independientes dentro de un programa; había una biblioteca de programas usuales que se identificaban por nombre: φsen, φlog, φpoly  (las funciones ya vistas).  El resto de los elementos de esta biblioteca se identificaban con la directiva programme-n  en la cual  n  es un entero en el rango 501-1023. Esta biblioteca de programas fue elaborada por usuarios de las computadoras Mercury, comenzando con el CML de la MU, donde se originó el lenguaje Autocode. [6]
El proyecto COMIC 

A mediados de la década de los sesentas, en el Instituto de Cálculo, se estaban manifestando las carencias del lenguaje AUTOCODE para expresar en forma “amistosa” las cada vez más complicadas fórmulas y ecuaciones que los científicos estaban empleando, –tal vez por la existencia de las computadoras– desde la rigidez en los nombres de las variables (“¿por qué no puedo llamar PBT al Producto Bruto Interno y POBT a la Población Total para saber de qué estoy hablando al analizar mis fórmulas?”),  la escasa flexibilidad para escribir las instrucciones (“¿por qué no puedo usar paréntesis, en lugar de desmembrar mis fórmulas en pequeños trozos y darles a cada uno otro nombre para luego ir reuniéndolos?”), hasta el engorro para realizar operaciones con matrices y vectores. 

Desde su ingreso al IC como programador novato, WOD estuvo interesado en saber cómo funcionaba el compilador AUTOCODE, del cual sólo se conocía un manual [7] y podía eventualmente imprimirse su código objeto. Este interés lo llevó a una larga y penosa tarea de lo que se denomina “ingeniería en reversa del código” –actualmente prohibida por las grandes empresas que “licencian” sus programas– que comenzó con la introducción en la máquina de pequeños programas con diversas instrucciones cuidadosamente escogidas para ver como las compilaba. No existía aún bibliografía donde pudiese estudiarse este tema tan nuevo. El conocimiento adquirido por este estudio le permitió saber como escribir programas en forma más eficiente, sobre todo con respecto al espacio ocupado en memoria, y convertirse en consultor de otros. Además, como prueba de haber aprendido algo, hizo algunos cambios en el compilador que resultaron bien y fueron incorporados al mismo.

Si reunimos la información presentada en los dos párrafos precedentes, no debe extrañar que, al reunirse el Dr. Oscar Varsavsky (quién dirigía la fuerte Sección de Economía Matemática del IC) con el Dr. Sadosky, le solicitara que tratara de facilitar su trabajo, pues la comunicación de los economistas, sociólogos y estadísticos de la sección con la máquina se veía fuertemente afectada con cosas tan triviales como los nombres de sus variables,  y de los programadores de la sección que eran los intermediarios entre ambos lados, con la posibilidad de errores constantes al tener que escribir o cambiar los diversos programas que se generaban. Como consecuencia de esta reunión, el Dr. Sadosky le preguntó a WOD si se animaba a encarar la tarea.  La respuesta fue afirmativa, por no saber en qué problemas se podía meter. 

Y así comenzó todo. La Sección Programación, dirigida por WOD e integrada por CZ y CDC, cambió su nombre a Sección de Sistemas de Programación, se mudó a una oficina mucho más amplia, en la cual se hizo una pizarra del piso al techo para poder tener a la vista la totalidad del diagrama de flujo del programa. También obtuvimos el préstamo –temporal, no cesión permanente– de las programadoras LSL y NSG de la Sección Economía Matemática, las cuales sabían por experiencia personal los problemas que causaba el lenguaje.

Y así terminó todo: “Oscar Varsavsky (…) iba en camino de convertirse en un experto en “modelos de experimentación numérica en computadora”, como él mismo prefería llamar a los más generalmente designados “modelos matemáticos”, que son representaciones matemáticas de un sistema o proceso real  (...)  Varsavsky reunió a jóvenes estudiantes y graduados como (...) Liana Lew, Noemí García, (...) economistas como Arturo O’Connell y A. Fucaraccio, sociólogos como Jorge Sábato y estadísticos como Víctor Yohai para intentar la modelización de los flujos de bienes y servicios que constituyen un sistema económico. (...)  A pedido de Varsavsky y para superar las limitaciones del Autocode en el desarrollo del modelo econométrico, Wilfred Oscar Durán diseñó y redactó, entre 196[5] y 1966, con la colaboración de Ana Cristina Zoltan [y] Clarisa Cortés, (...) un lenguaje y compilador que denominó COMIC (COMpila-dor del Instituto de Cálculo), que fue la primera experiencia de software de base en la Argentina.” [8]

Ahora había que trabajar...

El lenguaje y compilador COMIC  

Un programa compilador incluye dos partes bien diferentes, que podemos llamar “traductor” y “biblioteca numérica”.  
El traductor lee y analiza todas las instrucciones que el usuario escribe para determinar si están ajustadas a las reglas establecidas y las traduce por su equivalente en lenguaje de máquina. Es una actividad eminentemente lógica: ningún cálculo de los pedidos por el programador se hace hasta que la traducción finalice.
La biblioteca numérica contiene todas las “rutinas” que son llamadas por el programa generado por el traductor  para  hacer todos los cálculos que la unidad aritmética no puede hacer directamente (en la Mercury sólo hace la suma, resta y multiplicación). Veamos primero como está formada la biblioteca numérica.

Las funciones más corrientes tenían nombre mientras las menos frecuentes se identificaban con números. El código de las más frecuentes residía en memoria principal, mientras las otras de biblioteca se traían del tambor cuando se requería. El programador podía hacer sus propios subprogramas y usarlos empleando el sistema de paginación del mismo. Antes de la existencia de las computadoras electrónicas, los cálculos se hacían con calculadoras mecánicas, con la ayuda de tablas entre las que destacan [9] y con fórmulas aproximadas diseñadas por los especialistas en cálculo numérico; era una tarea pesada, tediosa, y propensa a los errores. Al comenzar la era de las computadoras digitales un cambio de metodología en los métodos numéricos, con nueva bibliografía [10] Este libro fue consultado por nuestro equipo, determinamos que los procedimientos empleados en el AUTOCODE eran lo suficientemente aproximados  y se conservó prácticamente toda su biblioteca numérica.

Los principales inconvenientes que los usuarios del lenguaje AUTOCODE denunciaban eran 
•	la rigidez en los nombres de las variables – una letra 
•	no se podían escribir fórmulas algebraicas complicadas – faltaban los paréntesis
•	el engorro para efectuar operaciones matriciales – direcciones y funciones son números 

Los dos primeros problemas se debían a la decisión por parte de los creadores del lenguaje de la yuxtaposición de los factores para indicar la multiplicación en las expresiones algebraicas. Esta decisión, unida a la de que los paréntesis se emplearan para agrupar las operaciones en subíndices limitaba enormemente las expresiones admisibles. El cambio de la “yuxtaposición” por un “separador” –como para las otras operaciones– elimina el problema, pero esto significa un cambio total del traductor. El escogido fue el ahora corriente  “*” asterisco, introducido por el FORTRAN. El árbol de decisión del traductor es más simétrico y permite emplear “palabras” donde antes sólo podían usarse “letras” y el uso más racional de los paréntesis, que ahora pasan a ser dos separadores más. 

Este cambio también facilita resolver el tercer problema: ahora las operaciones matriciales pueden escribirse más matemáticamente; las matrices ahora pueden tener nombres, no direcciones en los tambores. Sus dimensiones se declaran y no se pasan como parámetros en las operaciones. Como ahora las operaciones entre matrices usarán símbolos ( +, -, *, ’, ^ ) que podrían confundirse con sus homónimos con variables reales, creamos una nueva “seudo-función” que llamamos  φM  definida como “mi argumento es una operación matricial”, por ejemplo:  φM(a=b^-1*c), que resuelve n sistemas de ecuaciones lineales, si  b es cuadrada y  a y c tienen n columnas. 

Si bien procuramos hacer al COMIC lo más parecido posible al AUTOCODE, para facilitar la mudanza a quienes ya usaban éste, obviamente –como en el párrafo anterior– los cambios fueron importantes; describamos ahora los mayores. 
Los nombres de las variables son definidos por el programador, pudiendo emplear las 26 letras del alfabeto inglés y los dígitos del 0 al 4  comenzando con una letra; sólo los primeros 6 son significati-vos, pero el nombre puede tener hasta 56. La única excepción corresponde a las variables lógicas, que tienen prefijado el nombre £, seguido por un subíndice. El lenguaje no tiene palabras reservadas: las palabras del lenguaje son precedidas por el símbolo φ para distinguirlas de las variables; casi todas definen funciones, instrucciones o directivas, pero algunas indican constantes, como φV, φF y φI, las cuales corresponden a los valores verdadero, falso, y la matriz unidad, respectivamente. 
Los tipos de variables existentes son las 54 enteras (ex-índices, 12), reales (ex–especiales), vectores reales (ex–principales), 80 lógicas (no existían), todas residentes en la memoria actual, las matrices (ex–auxiliares) y los vectores matriciales (o matrices tridimensionales, no existían) todas residentes en los tambores. Todas las variables (menos las lógicas) deben declararse antes de ser usadas, con las directivas φventeras, φvreales, φvectores y φmatrices, declarando sus nombres y dimensiones.
Las expresiones algebraicas se construyen con variables y constantes y los símbolos + , -  , *, /  y  ^ (potenciación). Precedencias: (1) ^  (2) * y  /  (3)  +  y  - . Las alteraciones a este orden se obtienen usando paréntesis;  se permiten hasta 25 niveles de paréntesis anidados. En las expresiones algebraicas se permiten operaciones entre operandos reales y/o enteros; si el resultado debe colocarse en una variable entera el resultado se trunca.  La mayoría de las funciones admiten como argumentos expre-siones aritméticas encerradas entre paréntesis. Las instrucciones aritméticas se escriben: 
variable = expresión algebraica    o    variable = función.
En el COMIC se agregaron variables lógicas con las operaciones lógicas (Booleanas)  y constantes lógicas:  φV (verdadero) , φF (falso). Las expresiones lógicas eran similares a las de los lenguajes de programación actuales salvo que las expresiones que involucraban los operadores  = ,    ╪ ,   >,    ≥ , (comparaciones aritméticas)  estaban precedidas de un = . Por ejemplo: se desea guardar para uso futu-ro la respuesta a ¿la ecuación de segundo grado  ax^2 + bx  + c = 0  tiene  dos raíces reales y diferen-tes?  Podemos usar la siguiente instrucción lógica:   £(5) = (= a ╪ 0) * (=  b^2 – 4 * a*c  ≥ 0.
Veamos ahora el cálculo matricial que tenemos disponible en COMIC. Todas las operaciones  pueden emplearse tanto con matrices como con elementos de vectores matriciales. Si se desea efectuar una operación con todo el vector matricial basta con hacer un ciclo alrededor de la operación hecha con uno de sus elementos. Las limitaciones de espacio impusieron las siguientes restricciones:
--en ninguna instrucción se permiten más de dos operandos. 
--en algunas operaciones no se permite reemplazar uno de los operandos por el resultado. 
Las operaciones son
Combinaciones lineales:   φM ( A = ±x * B ± y * C )  donde x,  y  son escalares,  puede faltar cual-quiera de los componentes, y  C puede reemplazarse por  φI, que representa a la familia de constantes  matriz unidad. 
Trasposición:       φM ( A = B’ )  
Inversión:             φM ( A = B^-1)  
Multiplicación:    φM ( A = B * C ) donde se admiten las variantes  
                              φM ( A = B^-1 * C )    y     φM ( A = B * C’ ).  
Determinante:     φM ( x = φdet ( A )) donde x es una variable real o entera.
Diagonal:             φM ( A = φdiag ( B )) donde A es una matriz de una fila o una columna.
La factibilidad de las operaciones es controlada por el compilador. 
Ejemplo: el modelo de Leontiev, que responde al sistema lineal representado por   (I – A).X = D;  se puede resolver con las instrucciones:     φM ( A = -A  + φI )  ;      φM ( X =  A^-1 * D )

El sistema de marcas de instrucciones del AUTOCODE fue conservado, mejorando las instrucciones de control y paginación. A los saltos condicionales se les agregaron otros con varias formas para las condiciones, especialmente para admitir el uso de las variables y expresiones lógicas. 
Se diseñó la forma de escribir rutinas en forma independiente del resto del programa. Es un trozo de código precedido por la directiva φrutina  n  y terminado por  asterisco. Debe incluir la instrucción φvolver para  retornar al lugar de llamada. Cuando el compilador está traduciendo el programa y encuentra  φrutina  n  deja de traducir y guarda en un lugar temporario todas las instrucciones hasta encontrar la línea con  *  y reanuda su traducción normal; al terminar ésta, compila la rutina y la coloca en cada capítulo del programa (una vez por capítulo) donde se la mencione  con una de las instruccio-nes   φarutina(n)  o  φarutina(n/p) donde p es una  marca en la rutina.

A las instrucciones para la entrada de datos y la salida de resultados, ambas por cinta perforada,  se les agregaron nuevas instrucciones para flexibilizar el uso del teletipo y agregar todas las operaciones para la interacción con la impresora de línea recientemente comprada. Las instrucciones para la salida gráfica de resultados para emplear el graficador (plotter) adquirido por el IC, fue el primer aporte por un alumno avanzado en la carrera (CZ) de su trabajo de grado al COMIC. CZ programó las instruccio-nes para controlar este equipo, diferente a lo conocido por nosotros hasta entonces (salida analógica, no digital).  Para simplificar el trabajo del usuario, se llevó la programación al punto en que  bastaba una sola instrucción de COMIC para graficar una función, dando el número de la rutina que calculaba los puntos que definían la curva, la escala y el modo de dibujar (puntos, líneas, símbolos). 
Y así terminó todo...

Vida del lenguaje

Cuando se produjo el golpe de estado en junio de 1966 nuestro equipo seguía trabajando en el compilador COMIC, el cual no dimos por terminado nunca. Entre las mejoras que estábamos intentando implementar, se encontraban las dimensiones dinámicas de las matrices, las cuales se podían hacer con las herramientas que ya existían, pero no era cómodo para el usuario no iniciado;  las funciones recursivas, para las cuales se estaban implementando unas tablas de retornos internas, y algunas otras cosas.
	
Para finalizar esta exposición, WOD solicita la palabra al resto del equipo:
El día 26 de julio de 1966, tenía en mi escritorio un rollo de cinta perforada, con varios “remiendos” de inserciones posteriores, rotulada  “COMIC – CINTA MAESTRA |  NO USAR EN CONSOLA | 2/5/66 INCLUYE  φGRAFICAR” y decidí ir a la computadora para hacer nuevas cintas del COMIC y del AIC. Antes de hacerlas, en charla con MS, le pedí permiso para cambiar el “NO ANDA” que el COMIC imprimía al terminar de listar los errores en un programa que se intentaba compilar, por “NO ANDA, MI GENERAL” para ser respetuosos con quién lo suplantara, pero, sonriendo, se negó. Todavía tengo los rollos; los guardé porque nuestra salida del IC, con la visión optimista que nos contagió el Dr. Sadosky, pensamos que no podría ser muy duradera; para mí, 40 años (¿existirá aún una lectora de cinta perforada?). Otra anécdota de rollos. Unos tres meses después, otro ex-miembro del IC, Marcelo Larramendy, me dijo que alguien lo había llamado para avisar que el nuevo Secretario de la Facultad quería que fuese a verlo o me mandaba a buscar con la policía. Ante tan convincente invitación, fui. Tomando un papel de su escritorio me dijo que faltaba el “original inglés” del COMIC, y como yo era el responsable de esas cosas en el IC, quería que se lo entregara. Casi riéndome le dije que no había original inglés porque ese programa lo había escrito yo, y agregué que el Copyright lo había hecho a mi nombre, no al IC, (no existía Copyright para programas entonces) y tenía que pensar si se los iba a dejar usar. Me echó de su oficina no muy académicamente. 

Las integrantes del equipo LSL y NSG presentaron sus trabajos de grado con aportes a  COMIC.
El día 29 de julio de 1966, por la tarde.
En la sede de la Facultad, Perú 222.
Donde por la noche apareció la Policía Federal.
Con los bastones largos.
Venían a informarnos de la “ley”  16912.
Y ya nadie se acuerda de qué trataban los trabajos aprobados. Ni del COMIC.
Y yo escribo esto llorando. Porque soy un viejo sentimental.

Bibliografía 

[1] Traducido del folleto An Introduction to the Ferranti Mercury Computer, April 1956
[2] Ver  http://www.softwarepreservation.org/projects/FORTRAN/paper/Glennie-Automatic_Coding-1952.pdf   
[3] Ver  http://www.softwarepreservation.org/projects/FORTRAN/paper/Backus%20and%20Herrick%20-   %20Speedcoding%20-%20ONR%201954.pdf  
[4] Ver los 52 boletines en  http://archive.computerhistory.org/resources/text/algol/algol_bulletin/  
     Ver un reporte completo sobre el ALGOL 60 en  http://www.masswerk.at/algol60/report.htm  
[5]  http://www.softwarepreservation.org/projects/FORTRAN/paper/Laning%20and%20Zierler%201954.pdf 
[6] En la pág. 41 de [7] está la lista de usuarios de Mercury en los años sesentas
[7] Ver el Manual en  http://elgranerocomun.net/IMG/pdf/El_Lenguaje_AUTOCODE.pdf 
[8] Tomado de N. Babini, en LA INFORMATICA EN LA ARGENTINA 1956-1966.  
[9] British Association for the Advancement of Science, Mathematical Tables, Vol 1, 1946 
     NBS, M. Abramowitz y I. Stegun (editores), Handbook of Mathematical Functions, 1964 
[10] C. Hastings Jr. con J. Hayward y J. Wong, Approximations for Digital Computers, 1955