¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (1)

This entry is part 1 of 6 in the series CS

Saltándome los ábacos y esas cosas, todo comenzó en los años 30 con los trabajos de Gödel (1931: “Über formal unentscheidbare Sätze der Principia Mathematica und verwandter Systeme.”), Turing (1936: “On Computable Numbers, with an Application to the Entscheidungsproblem”) y  Church (1936: “Formal definitions in the theory of ordinal numbers”).

El fundamento matemático está, por un lado, en los lenguajes formales y la teoría de autómatas, teniendo mayor poder expresivo los lenguajes recursivamente enumerables, que son decididos por las máquinas de Turing y son caracterizados por las gramáticas no restringidas.

El fundamento matemático está, por otro lado, en la lógica (proposicional, de predicados de primer orden, y otras).

En ambos mundos nos encontramos con cosas entretenidas como el teorema de incompletitud de Gödel, problemas de decisión, y complejidad computacional.

Otros fundamentos matemáticos están en las matemáticas discretas, con cosas como los grafos.

Me contó del primero Álvaro Campos, del segundo Leopoldo Bertossi, y del tercero Yadran Eterovic (como parte de la discusión de estructuras de datos).

La clave está en el concepto de algoritmo, y la tesis de Church-Turing.

¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (2)

This entry is part 2 of 6 in the series CS

Ya vimos los fundamentos teóricos, que conforman la base de la ciencia de la computación. Pero la teoría no basta, hace falta la máquina. Me voy a saltar los dispositivos mecánicos (ábaco, pascalina, regla de cálculo, dispositivo diferencial).

Me saltaré también los dispositivos electromecánicos desarrollados antes de la segunda guerra mundial por IBM, aunque su historia es interesante. IBM básicamente se fundó porque USA hacía censos cada 10 años, y el de 1880 tomó siete años en ser procesado, y se proyectaba que el siguiente tomaría más de diez años en ser procesado. El fundador de IBM, con sus máquinas, obtuvo el resultado del censo de 1890 en 2,5 años.

El punto de inflexión es en la década de los 40, (con la guerra, claro) cuando aparecen los capacitores, los tubos de vacío y los relés. Ellos permiten crear los circuitos electrónicos, en particular, funcionan como interruptores: encendido, apagado, encendido, encendido, apagado, 10110, … o sea, permiten los circuitos digitales (1937).

Estos elementos junto con el uso de tarjetas perforadas para entrada / salida, fueron usados para implementar las ideas base de la teórica máquina de Turing. Esta implementación es lo que conocemos como arquitectura de Von Neumann.

Esa es la arquitectura del primer gran computador digital, el ENIAC(1943) y, con ligeras modificaciones, del PC donde escribo este post.

El resto es miniaturización, con el transistor, y luego con los circuitos integrados, y por último con el microprocesador.

Pero aun estamos lejos de decir que con esto termina el camino que llevó a los computadores a ser parte de nuestra sociedad.

¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (3)

This entry is part 3 of 6 in the series CS

Ya vimos los fundamentos teóricos y eléctricos. Lo siguiente fue hacer que la máquina hiciese lo que nosotros queríamos.

Para ello, hay que pedírselo, y eso se hace por medio del lenguaje. Al comienzo, directamente. Si la máquina entiende con ceros y unos, se le hablaba en ceros y unos. De esa manera, uno le da instrucciones a la máquina (instrucciones que están implementadas en los circuitos).

Al rato uno se da cuenta que esa forma es un poco lenta, y que se cometen muchos errores. Entonces inventemos palabras (mnemotécnicos) que representen lo que queremos decir con los ceros y unos. Hacemos que esto sea procesado por un programita (ensamblado se decía en esos tiempos) que genere directamente los ceros y unos. A esto se le llamó el lenguaje ensamblador, y la idea era así:

toma el valor del registro X y cárgalo en el acumulador
suma lo que está en el acumulador con el valor del registro Y
carga el valor del acumulador en el registro X

Esto se veia así:

LDA X
SUM B
LDX A

Ahora se podrán imaginar que con ese nivel de abstracción, pedirle a la máquina cosas como “itera hasta que el número sea mayor que mil” se hace eterno.

Salieron entonces (en los sesenta) los lenguajes con una sintáxis y semántica un poco más cercana a la humana, donde uno puede decir, casi directamente:

haz (hasta que X sea mayor que mil) lo siguiente:
[alguna cosa que repetir]

Y .… básicamente hasta acá llegamos.

Q. ¿pero cómo, no evolucionó más eso?
R. La verdad sí evolucionó un poco más, pero lo que más se usa es lo descrito.

Los lenguajes más “modernos” consisten en mecanismos más gráficos para hacer lo mismo, con facilidades de “drag and drop”. Pero estos elementos no cubren el 100% de lo que se necesita para hacer que la máquina haga lo que sea que uno quiera que haga.

Q. Pero cómo, Felipe, ¿me dices entonces que los programas que uso están escritos de una manera similar a la que se escribian hace cuarenta años?
R. Sí. Pero ahora tienen millones de instrucciones, y mayor variedad de dispositivos para interactuar con los seres humanos.

Por ejemplo, este mismo software para escribir blogs tiene instrucciones como la siguiente:

for ( $i = 0; $i < $num_drafts; $i++ ) {
$draft = $drafts[$i];
if ( 0 != $i )
echo ‘, ‘;
if ( empty($draft->post_title) )
$draft->post_title = sprintf(__(‘Post # %s’), $draft->ID);
echo “<a href=‘post.php?action=edit&post=$draft->ID’ title=’ ” . __(‘Edit this draft’) . “ ‘>$draft->post_title</a>”;
}

Bonito, ¿no? Veremos cómo realmente esto llega al ser humano común más adelante en esta serie. Aquellas personas que son capaces de pedirle a la máquina que haga cosas son los llamados programadores.

¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (4)

This entry is part 4 of 6 in the series CS

Hablamos de la parte electrónica (fierros), de los fundamentos teóricos, y de los lenguajes.

Sucedió entonces que se tenían grandes y caras máquinas (mainframes) que podían ser programadas, y cada segundo que la máquina no trabajaba era un tiempo muerto muy, muy caro. Se asignaban ‘lotes de tiempo’ a los distintos usuarios de las máquinas, para que cargaran sus programas, los ejecutaran, y luego esperaran los resultados.

Se dieron cuenta que eso se podía optimizar si se hacían lotes (batch) de trabajos (jobs), que se calendarizaban (scheduling), de manera que la máquina estuviese mayor tiempo ocupada. Eso se llamó ‘time sharing’, compartir el tiempo de la máquina.

Pero ¿quién organiza esto de los jobs y scheduling? Se les ocurrió escribir un programita ‘especial’ llamado monitor que hiciera la tarea de organizar la ejecución de los otros programas. Así nacieron los sistemas operativos.

En esos primeros tiempos, todos los programas tenían iguales derechos de acceso al procesador y a los periféricos. Conforme la idea del ‘time sharing’ fue ganando impulso, los fabricantes de procesadores comenzaron a inventar un espacio especial de ejecución (rings) para el programa que controla a los otros programas. O sea, le estaban dando privilegios especiales.

Entre esos privilegios especiales, estaba poner en suspención (hold) un programa que estuviese corriendo, hacer un cambio de contexto (context switch), pasando toda su información a otro lado, cargar otro programa y ponerlo a ejecutar, y así con toda la carga de la máquina.

Comenzaron entonces a inventar algoritmos y métodos, para hacer mejor uso de los recursos de la máquina: procesador, administración de memoria, entrada/salida con periféricos. Estos sistemas operativos eran totalmente dependientes de la máquina, y se tenían que escribir (en ensamblador) para cada marca de procesador, a veces para cada generación de procesador.

Entonces en Bell Labs a principios de los setenta inventaron UNIX, y pronto (el ’73) una versión en lenguaje C. Una maravilla, porque era esencialmente gratis, en lenguaje de alto nivel, y con el código fuente incluído. Muy portable, y se hizo muy popular. Comenzó a comercializarse y rápidamente estaba en todas partes.

Pronto aparte de la parte esencial del sistema operativo (kernel), comenzaron a aparecer aplicativos secundarios que venían con el sistema. Editores de texto, ambientes de línea de comando (shells), y otros, enriqueciendo el ambiente de usuario.

Y acá acabaría esta parte de la historia, si agregamos llamadas al sistema (interrupciones), hilos de ejecución (threads), redes (networking), inter-process communication (IPC) e interfaces gráficas de usuario (GUI), entre otras cosas. Pero ustedes saben quién llegó a principios de los ochenta. Bill Gates. ¿Qué sistema operativo estás usando en este momento para ver esta página? Hay una alta probabilidad de que sea Microsoft Windows.

Sucedió que el ’74 Intel inició la manufactura de una serie de chips muy barato, con el 8080, un juguete de 8 bits. Este no podía competir con los grandes procesadores de las máquinas serias. Un microprocesador.

Lo que nadie se imaginó, es que el mercado, lentamente al principio, comenzó a llenarse de máquinas baratas con este tipo de procesadores, a partir del 8086 el ’78. Individuos (no empresas) que querían meterse en el mundo de la computación compraron máquinas y comenzaron a usarlas en casa.

Entonces IBM, dueño y emperador del mercado de la computación, abrió una línea de negocio pequeña, secundaria, manufacturó estás máquinas de juguete, y las llamó Personal Computer. Nació el PC el ’81. Pero necesitaba un sistema operativo. Llegó Bill Gates, compró uno (no lo escribió), y lo licenció (no lo vendió). Nació MS-DOS.

Esta es la revolución, porque Microsoft mantuvo los derechos para vender el sistema operativo a terceros, desligándose del monopolio de IBM. Y vaya si lo hizo. Nacieron los clones. Baratos. Compatibles. E Intel lanzaba cada vez mejores procesadores compatibles retroactivamente. El 8086, el 80286, el 80386, el 80486, toda una arquitectura de procesadores.

Y simultáneamente con los bolsillos llenos, Microsoft fue sacando nuevas versiones de MS-DOS, que luego fue Windows, un éxito de mercado.

Pero volvamos al tema del post. Había una brecha que salvar. MS-DOS no heredaba casi nada del estado del arte de los sistemas operativos de los setenta. Nosotros los usuarios tuvimos que mamarnos su evolución y aprendizaje para tener multitarea, multithreading, administración de memoria, cuentas de usuario. Por eso vivimos años con las pantallas azules, porque ni MS-DOS ni Windows eran sistemas operativos profesionales.

Hasta que llegó Windows NT el ’93. Recién ahí pudo comenzar a competir Windows con Unix, y tímidamente. Entretanto (el ’91) nacía el fenómeno Linux.

Pucha que me está saliendo larga la historia, pero es que esta es muy buena!

Linux Is Not UniX. Lo escribió (el kernel) Linus Torvalds,  clonó el comportamiento e interfaces de Unix. Y lo hizo open source. Esto fue clave, porque comenzó a haber un equipo mundial de personas (habilitado por la emergente internet) trabajando por mejorar este nuevo concepto.

Poco a poco se convirtió en un competidor de mercado. Grandes empresas comenzaron a distribuir Linux (open source no significa gratuito), y hoy hay gobiernos y grandes corporaciones que lo usan en vez de Unix, y en vez de Windows.

Pero Felipe, ¿y Apple? No lo olvido. Su historia es la del alter ego de Windows, pero nunca le fue tan bien. Porque su arquitectura fue por muchos años cerrada, a diferencia de la Wintel.

Ya, mucho por hoy.

¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (5)

This entry is part 5 of 6 in the series CS

Estuvo muy bonito eso de tener lenguajes para poder pedirle a la máquina que haga lo que uno quiera. ¿Qué se le puede pedir a la máquina que haga?

En un principio, calcular. Los científicos querían calcular trayectoras, para aplicaciones militares / aeroespaciales, modelos estocásticos, modelos de optimización, simulaciones, fuerzas y tensiones en estructuras.

Pronto se dieron cuenta de algo. El hardware evolucionaba mucho más rápido que lo que le podían sacar provecho con el software. ¿Por qué? Porque el desarrollo de aplicaciones no le alcanzaba el ritmo.

Los sintomas: Proyectos que no lograban sus metas de tiempo, costo y calidad. Proyectos cancelados, abortados, o que entregaron bastante menos de lo prometido.

Era necesario reconocer que las prácticas de desarrollo a la fecha no eran disciplinadas. En el tiempo de los gurús, unos pocos especialistas realmente eran capaces de programar las máquinas. Hacer depuración era todo un arte. Y nadie ‘de la oficina’ era capaz de intervenir en esa área técnica.

Pasó el tiempo de los gurús, había más programadores, las máquinas eran más baratas, pero el estado del arte de los equipos de programadores no estaba a la altura de las necesidades. Pronto aparecieron proyectos con decenas, cientos, y miles de participantes, y todos se preguntaban ¿cómo administro estos proyectos para lograr las metas? En 1968 a esto se le denominó la Crisis del Software.

Los interesados en superar esta situación comenzaron a trabajar en lo que hoy se conoce como ingeniería de software.

¿De qué se hace cargo esta disciplina? De dos cosas: a) de los aspectos técnicos de desarrollar software. b) de los aspectos administrativos de desarrollar software.

Aspectos técnicos

Responde a las siguientes preguntas: ¿cómo entender lo que necesita el cliente? ¿cómo especificar estas necesidades de una manera tal que los especialistas puedan desarrollar software? ¿cómo diseñar software a partir de estas especificaciones? ¿cómo desarrollar software? ¿cómo verificarlo y validarlo? ¿cómo ponerlo en marcha? ¿cómo operarlo y mantenerlo?

Esas preguntas abarcan el ciclo de vida del software. Para realizar esas actividades, nacieron los procesos de software, y se adaptaron los diversos paradigmas de desarrollo (estructurado, orientado a objetosfuncional, etc.).

De particular interés hoy es un tema de la arquitectura de software: el reuso. ¿Cómo organizar el software en diversas unidades (componentes), de tal manera de no tener que escribirlas siempre desde cero? Las respuestas sucesivas fueron el linkeo estático, el linkeo dinámico (las DLL), frameworks como MFC, y luego elementos más autónomos, como OLE y COM. Con la llegada de las redes, comenzó a nacer el concepto de componentes distribuidos, con RPC, CORBA, y DCOM. Todo esto evolucionó a lo que hoy conocemos como arquitectura de servicios, con .NET y J2EE.

Aspectos administrativos

Son más genéricos, y responden a preguntas tales como ¿cómo administro uno o varios proyectos? ¿cómo capacito al personal? ¿cómo gestiono la calidad? ¿cómo administro las distintas versiones de lo que se está desarrollando? ¿cómo hago monitoreo y control de los proyectos? ¿cómo adminsitro a proveedores?

En los ’80 se consensuó que el problema central en la crisis del software es administrativo, no técnico. Por ello se desarrolló lo que hoy se conoce como CMMI, que es un modelo de buenas prácticas para obtener una unidad de desarrollo de software cuyos proyectos terminan en tiempo y costo, a un nivel de calidad conocido y predecible, y que mejora en el tiempo.

Todo lo conversado hoy está sistematizado en lo que se llama el Software Engineering Body of Knowledge.

En la medida que todos tienen un computador a la mano, y que se puede conseguir herramientas de desarrollo gratuitas, prácticamente cualquiera puede ser hoy desarrollador de software. Un profesor de la universidad me decía una vez que, cuando le contaba a un apoderado del colegio que él trabajaba en el Departamento de Ciencia de la Computación, el otro respondió “ah, sí, mi hijo de segundo medio hace lo mismo”.

Este tipo de posibilidades abiertas hace que la superación de la crisis del software aún no sea una realidad para la mayoría de las empresas que desarrollan o mandan a desarrollar software.

¿Cómo fue que los computadores llegaron a ser parte de nuestra sociedad? (6)

This entry is part 6 of 6 in the series CS

La teoría está cerca de los científicos y matemáticos. Las máquinas y circuitos, cerca de los ingenieros y técnicos. Los lenguajes de programación, sistemas operativos, e ingeniería de software, cerca de los computines.

Ahora recién, en la parte cinco de esta serie, vamos a comenzar a llegar a la sociedad. Con la interfaz de usuario.

Para darle instrucciones a la máquina, con estos lenguajes que ya hemos nombrado, en un principio había que literalmente recablearla, de manera que la lógica formase parte de sus principios.

Más adelante, se incorporaron interruptores, donde el operador iba seteando instrucción por instrucción.

Vinieron entonces las tarjetas perforadas, que nos acompañaron hasta los setenta. Los programadores preparaban cajas de tarjetas que eran recibidas por un operador del computador. Este operador iba entregando al computador cada trabajo (job) secuencialmente, y luego de varias horas se podía ir a buscar el resultado (o el error dado por la máquina). Estos jobs tenían control total sobre la máquina.

Llegaron entonces, con el desarrollo de los sistemas operativos, los ambientes interactivos, con teclado y pantalla. Los programadores de esa época estaban maravillados de poder apretar la tecla ‘a’ y ver inmediatamente un caracter ‘a’ en pantalla.

Esta forma de interactuar era por medio de una interfaz de línea de comando (shell), como la bien conocida de MS-DOS. Si nuestros padres alcanzaron a ver tarjetas perforadas (yo nunca he visto una), fuimos nosotros quienes podemos decir que trabajamos con línea de comando.

Esta shell recibe los comandos de la persona que está usando el computador (desaparece o disminuye el rol de un operador), y los transfiere a la máquina, por ejemplo así:

curl “http://en.wikipedia.org/wiki/Pipeline_(Unix)” | \
sed ‘s/[^a‑zA‑Z ]/ /g’ | \
tr ‘A‑Z ’ ‘a‑z\n’ | \
grep ‘[a‑z]’ | \
sort ‑u | \
comm ‑23 — /usr/dict/words

Esa instrucción encadena seis programas.

En los ochenta, sobretodo gracias a Apple, llegan las interfaces gráficas de usuario (GUI). Aparecen elementos (widgets) tales como botones, ventanas, cuadros de texto, barras de desplazamiento, cursor y mouse. Como que recién desde este momento, podemos decir que la interfaz de usuario está a un nivel de acceso masivo al público.

Ahora vemos terminales de autoconsulta (TAC), kioskos virtuales y sistemas de búsqueda de novios en las multitiendas, por ejemplo. En casi todos los puestos de trabajo hay un computador de escritorio con aplicaciones que usan GUI.

Esto ha sido posible gracias al poder de las tarjetas de video, evolución de los monitores (de monocromáticos a VGA y superiores), y capacidades de los sistemas operativos.

Una de las gracias de Microsoft es que universalizó la GUI. Todos esperamos ver un menú en nuestras aplicaciones donde la ayuda está a la derecha y aparece apretando F1. Todos esperamos que exista un menú ‘archivo’ con opciones abrir, guardar, imprimir. Esta consistencia en la interfaz ha logrado masificar el uso de estas aplicaciones.

Sigamos. A finales de los noventa, comenzaron las aplicaciones web. En un principio emularon las aplicaciones con ventanas, con botones, campos de texto y barras de desplazamiento, pero la arquitectura web había restringido la interactividad al exigir comunicación con un servidor para refrescar la página.

Apareció entonces el concepto de las aplicaciones dinámicas, con el uso de los lenguajes de script, que se ejecutan en el cliente web. Y lo último de la moda es AJAX, que simplemente es una técnica donde se puede actualizar una aplicación web sin necesidad de refrescar la página completa.

Hoy usamos estas aplicaciones para ver nuestra cuenta corriente, para pagar nuestras cuentas, para mandar correo electrónico, para escribir blogs, para subir fotos, para consultar enciclopedias, para hacer búsquedas. Son realmente masivas, de uso diario y frecuente.

¿Qué vendrá después? Saldremos de las superficies bidimensionales de las pantallas, con tecnología 3D; los dispositivos de bolsillo como los PDA serán cada vez más comunes; eventalmente integraremos tecnología en organismos biológicos.