Número 105, enero de 2000
EasyWriter fue el primer procesador de textos que, junto a la mítica hoja de cálculo VisiCalc, se comercializó como paquete de software estándar del recién nacido IBM-PC (el cual se presentó el 12 de agosto de 1981). Lo que por lo visto no sabía IBM es que EasyWriter fué escrito por un conocido "hacker telefónico" (su alias era Capitán Crunch) mientras cumplía sentencia en la cárcel tras ser arrestado cuando realizaba llamadas de larga distancia con su "blue box" (adoptó el nombre de Capitán Crunch tras descubrir que un juguete de regalo de las cajas de cereales del mismo nombre, emitía un tono que causaba que la circuitería de la red telefónica de Bell activara la línea de conferencia).
A estas alturas ya habrá adivinado el lector que EasyWriter, el primer procesador de textos para el ahora ubicuo PC, fue una aplicación Forth. John Draper (el nombre real del autor) desarrolló una versión comercial de Forth para Apple II, y, puesto que EasyWriter estaba escrito en Forth, no necesitaba usar los servicios del sistema operativo, utilizando su propio formato de fichero. Esto permitía que el programa cargara en menos de tres segundos (recordemos que estamos hablando de los albores de la microinformática). Durante esa época, escribió un magnífico depurador para Forth que permitía seguir la ejecución del código paso a paso (algo totalmente inaudito en esos días). También escribió un decompilador que tomaba el código objeto Forth y regeneraba el código fuente, una utilidad inestimable para rastrear puntos clave de los programas cuando se presentaban problemas durante la compilación. Como se puede ver, Draper no sólo escribió un procesador de texto, sino que también colaboró en el desarrollo del lenguaje con el que lo había creado. Según él mismo comenta, encontró que Forth le permitía una flexibilidad total. Si el lenguaje carecía de alguna característica, la implementaba; así de simple.
A mediados de julio de 1981 la compañía de Draper firmó un contrato con IBM para portar EasyWriter al nuevo ordenador. Una vez estudiado el modo de funcionamiento de la CPU 8086, usó FIG-Forth para implementarlo en el mismo. En dos semanas había confeccionado el núcleo del lenguaje. La fecha de la presentación del nuevo ordenador se acercaba, y en IBM se mostraban totalmente asombrados de que, tanto el procesador de texto como el nuevo lenguaje, estuvieran operativos tan pronto, hasta el punto de mandar a sus mejores ingenieros para averiguar cómo podía haberse conseguido tan rápidamente.
(arriba)
El sistema de red original de Novell (1980-1981, o sea, antes de la
era PC) estaba escrito en Forth, según Dean Miller, y corría
sobre ordenadores S-100, que usaban el procesador Zilog Z80. Tal como él
cuenta, cuando arrancaba la red Novell se mostraba el inductor (prompt,
en inglés) de Forth, y podían ejecutarse palabras habituales
de este lenguaje.
Todo lo que necesita conocer sobre STATE, IMMEDIATE y POSTPONE
Usando y controlando STATE.
STATE es una bandera (flag, en inglés) que indica a los programas cuándo el intérprete de texto está en modo interpretación y cuándo en modo compilación (por ejemplo, al crear una nueva palabra). En tiempo de compilación, STATE puede ser cambiado temporalmente al modo intérprete usando la palabra [, y retornado al modo compilación mediante ]. Para entender esto último se muestra el siguiente ejemplo:
VARIABLE X
: TEST1 [ X @ ] LITERAL
;
: TEST2 X @ ;
En TEST1, X @ es interpretado durante el modo compilación, y el resultado se almacena de forma perenne en la nueva palabra. En TEST2, se mostrará el contenido de X cada vez que se ejecute la palabra, mostrando el valor que dicha variable tenga en cada momento.
' nombre devuelve la
dirección del código ejecutable de la palabra nombre.
Si a continuación de lo anterior añadimos la palabra EXECUTE,
dicho código se ejecutará. A EXECUTE
le resulta indiferente el modo en que se encuentre STATE,
con lo que realizará su labor en cualquier caso, ya sea en modo
de intérprete o de compilación. Así es como el intérprete
de texto trata las palabras IMMEDIATE,
y las normales cuando se encuentra en modo intérprete. Si se encuentra
una palabra normal durante la compilación, el intérprete
de texto añade su semántica de ejecución (su "código",
vamos) en la palabra que se está compilando. La palabra estándar
para esto es COMPILE,.
Palabras inmediatas.
Cuando se encuentra una palabra inmediata durante la compilación, esta se ejecuta en vez de compilarse. Estas palabras son fáciles de crear: basta con añadir la palabra IMMEDIATE justo después de su definición. Se pueden hacer inmediatas palabras, variables, constantes y, en general, cualquier cosa que se pueda nombrar. FIND puede distinguir entre palabras inmediatas y normales. Esta palabra devuelve la dirección del código de la palabra buscada y una bandera, que será -1 para las palabras normales, y 1 para las inmediatas. EXECUTE y COMPILE, no tienen en cuenta la naturaleza, inmediata o no, de las palabras con las que trabajan.
Este es un diseño simple de un intérprete de texto:
BEGIN
BL WORD FIND
DUP
WHILE
STATE
@
IF
\ ¿estamos en modo compilación?
-1 =
IF \ ¿es una
palabra normal?
COMPILE, \ añade el "código" a la definición
ELSE
EXECUTE \ es una palabra inmediata, así que la ejecuta
THEN
ELSE
\ estamos en modo interpretación
EXECUTE \ la ejecuta
THEN
REPEAT
2DROP
Son palabras inmediatas:
Palabras de sólo-compilación
Sabemos que hay palabras que sólo actuan en modo compilación (no en modo intérprete). Únicamente las palabras de comentario pueden ejecutarse sin tener en cuenta a STATE. El resto son palabras de "sólo-compilación", que no han de invocarse nunca directamente para su interpretación. POSTPONEnombre es la vía estándar para conseguir este comportamiento (de hecho, esta es una palabra de "sólo-compilación"). Si nombre es una palabra de este tipo, se añade su "acción en tiempo de compilación" a la definición en curso. Si es una palabra inmediata, se ejecuta en tiempo de compilación. Si es una palabra normal, se ejecuta en tiempo de ejecución. En cualquier caso, el código compilado con POSTPONE no puede ser invocado cuando se interprete la palabra en la que se encuentre. La única excepción posible es cuando nombre sea una palabra inmediata:
: MI( POSTPONE ( ; IMMEDIATE
que es equivalente a:
: MI( ['] ( EXECUTE ; IMMEDIATE
Esta última definición sería más correcta.
Palabras STATE-inteligentes
Son útiles cuando no deseamos que el usuario tenga que recordar dos palabras distintas con el mismo comportamiento, una para tiempo de compilación y otra para tiempo de interpretación. En Forth 83 existe la palabra ASCII, que puede ser definida así:
: ASCII STATE @ IF POSTPONE [CHAR] ELSE CHAR THEN ; IMMEDIATE
La acción en tiempo de compilación de ASCII se genera mediante la consulta a STATE. Cuando está compilando, es equivalente a [CHAR]. Cuando está interpretando, ASCII invoca a CHAR.
No obstante, las palabras STATE-inteligentes que usan POSTPONE pueden presentar problemas cuando, en modo compilación, deseamos que dichas palabras ejecuten su comportamiento típico de tiempo de interpretación. Una buena solución para esto (aunque muy liosa) es la siguiente:
: [[ POSTPONE [ ;
\ Establece STATE a off en tiempo de ejecución, no en tiempo de
compilación
: COMPINT
\ Compila el código equivalente al del modo interpretación
'
\ Extrae la dirección del código
POSTPONE STATE
POSTPONE @ POSTPONE IF
POSTPONE [[
\ Código que torna a off STATE (si está a on)
DUP COMPILE,
\ Compila la dirección del cógido
POSTPONE ]
\ y restaura STATE al modo de compilación
POSTPONE ELSE
COMPILE,
POSTPONE THEN
; IMMEDIATE
Usado así: CONTROL COMPINT ASCII >CONTROL ; produciría el siguiente código:
: CONTROL STATE @ IF [[ ASCII ] ELSE ASCII THEN >CONTROL ;
No obstante, el autor concluye su artículo con una sabia recomendación: evítese usar palabras STATE-inteligentes.
-----------
En el apartado Desde la Red, un bonito ejémplo de uso del cambio de base de numeración para resolver fácilmente una tarea (concretamente, mostrar una hora determinada, dada en segundos, en el formato elegido: HH:MM.SS).
DECIMAL
: SEIS 6 BASE ! ;
\ cambia a base 6
: .HMS ( n -- )
\ imprime la hora (dada en segundos) con el formato HH:MM.SS
0 <# DECIMAL
# SEIS # [CHAR] . HOLD
DECIMAL # SEIS
# [CHAR] : HOLD
DECIMAL # # #>
TYPE 1 SPACES ;
: >SEC ( h m s -- n )
\ pasa la hora dada a segundos
ROT 60 * ROT
+ 60 * + ;
Ejemplo de uso:
10 30 5 >SEC .HMS
Y el resultado sería: 10:30.05
(arriba)
El Cat no usaba ficheros. En vez de eso, guardaba todo el estado interno de la máquina (incluido el estado de la pantalla y la posición del cursor) en un diskette. Al encenderla, recuperaba dicho estado interno y ofrecía la impresión de arrancar instantáneamente en apenas un segundo. Después de unos 6 segundos, el cursor comenzaba a parpadear, lo que indicaba que ya estaba lista para su uso. Si el usuario pulsaba cualquier tecla durante esos 6 segundos, estas pulsaciones quedaban almacenadas en un buffer para su posterior procesado.
Resaltando el texto "Enable FORTH Language" y presionando una tecla denominada "Answer", esta tomaba la función de evaluar cualquier texto remarcado como código Forth. Además, introduciendo la deliberadamente críptica secuencia "use front" + "shift" + "space", la máquina entraba a un editor/intérprete de Forth interactivo. Cuando una palabra Forth ya estaba definida y probada, el usuario podía ejecutarla simplemente seleccionando el nombre en la pantalla y pulsando la tecla "Answer" (algunos años después Niklaus Wirth incluía una funcionalidad similar en su sistema Oberon).
Canon Cat tuvo una favorable acogida, y recibió algunos premios,
incluido el de los Diseñadores Industriales de América de
1989. Sorprendentemente, a los 6 meses de su puesta en el mercado, con
20.000 unidades vendidas, Canon lo descatalogó. Algunos rumores
apuntan como causa a luchas intestinas entre las divisiones de ordenadores
y la de máquinas de escribir de la compañía; otros,
señalan a presiones ejercidas por NeXT, la nueva compañía
de Steve Jobs, de la que Canon había adquirido el 16,67% de las
acciones en junio de 1989.
¿Sabía usted que ...?
En los días anteriores a que los microordenadores vinieran ya equipados con unidades de disco y un sistema operativo, Forth proveía de un entorno potente y perfectamente integrado que combinaba sistema operativo, aplicaciones y lenguaje de programación. Este diseño sobrevive comercialmente en la actualidad.
Para ser más específico, Greg Bailey at Athena Programming mantiene diversos OEMs, con un agregado de varios cientos de instalaciones con sistemas operativos Forth nativos, corriendo en PCs normales que proveen tanto aplicaciones de servicio como un ancho de banda extremadamente alto y elevada seguridad en servicios TCP/IP. Funcionan durante años sin necesidad de ser reinicializados, y poseen un rendimiento que excede el de cualquier servidor del mercado.
Gracias a esta cualidad, Forth ocupa un puesto único en la historia
del procesador 8086. Una de las primerísimas unidades de este modelo
fue entregada a FORTH Inc, y polyFORTH estuvo corriendo sobre él
en menos de dos semanas. Todo esto ocurrió antes de que DOS
y CPM/86 existieran.
(arriba)
Por su parte, Bernd Paysan, en Un servidor web en Forth, nos relata cuan facilmente puede trabajarse con cadenas de caracteres usando Forth (en contra de lo que mucha gente cree), al tiempo que muestra lo rápidamente que puede desarrollarse una aplicación como esta (en apenas unas horas), describiendo paso a paso su elaboración en un extenso artículo. La implementación del lenguaje escogida es Gforth.
Por último, en ¿Sabía usted que ...?, Elizabeth Rather (de Forth Inc.) cuenta como se desarrollaron dos soluciones, una en Forth y otra en C, para una misma aplicación real (una máquina virtual Open Terminal Architecture). La solución Forth ocupaba bastante menos memoria que la elaborada en C, siendo su rendimiento equivalente. "En mi opinión, este tipo de reto del mundo real es mucho más significativo que cualquier test de rendimiento", comenta Elizabeth.
(arriba)
: INTERCAMBIO ( dirmem
dirmem -- )
DUP @ >R OVER
@ SWAP ! R> SWAP ! ;
VARIABLE Numero-Secuencia 0 Numero-Secuencia !
: PERMUTACION ( tabla
num -- )
1 Numero-Secuencia
+!
Numero-Secuencia
@ 2 ROT ?DO \ tabla num
I
/MOD ( tabla resto cociente)
OVER
IF
1 AND IF
I SWAP - THEN \ tabla num
CELLS + DUP 1 CELLS - INTERCAMBIO
UNLOOP EXIT
THEN
\ tabla 0 cociente
NIP
\ tabla num
DUP
1 AND 0= IF >R CELL+ R> THEN
-1 +LOOP
CELLS + DUP 1
CELLS - INTERCAMBIO
0 Numero-Secuencia
! ;
\ LIMITES la he deducido
del resto del código, pues su definición
\ no venía en
el listado original. ¡Y esto sin dominar aún Forth!
\ Por supuesto, no es
mérito mio, sino del lenguaje.
\
: LIMITES ( dirmem longitud
-- dirmemFinal dirmemInicio )
over swap cells
+ swap ;
: IDUMP ( dirmem longitud
-- )
LIMITES ?DO I
@ . 1 CELLS +LOOP ;
CREATE X 12 CELLS ALLOT
: INICIALIZA ( -- )
X 12 1+ 0 DO
\ dirmem
I
1+ OVER ! CELL+
LOOP DROP ;
INICIALIZA
: PERMUTACIONES ( tabla
n -- )
0 Numero-Secuencia
!
BEGIN
Numero-Secuencia
@ OVER MOD 0= IF CR THEN
2DUP
IDUMP 2 SPACES
2DUP
PERMUTACION
Numero-Secuencia
@ 0= UNTIL
2DROP ;
CR X 3 PERMUTACIONES CR X 4 PERMUTACIONES CR X 5 PERMUTACIONES
Y, si en vez de una tabla, tomamos los números de la pila, tenemos otra solución:
: Permutaciones ( <items
a ser permutados> #items -- <items a ser permutados> #items )
DUP 1 = IF
CR
>R
.S R>
ELSE
DUP
0 DO
>R
R@ 1-
RECURSE \ Llamamos otra vez a Permutaciones con un número menor
de items.
ROLL
R>
LOOP
THEN ;
2 4 6 3 permutaciones
En ¿Sabía usted que ...? se habla sobre Open Firmware. Leemos:
Open Firmware fue desarrollado originalmente en Sun, y ha sido una característica de todas sus estaciones de trabajo desde 1986. En 1994 se convirtió en un estándar, el IEEE1275, y fue adoptado como arquitectura "plug-and-play" por el consorcio Power PC (Apple, IBM y Motorola). Se usó en todos los Mac fabricados desde 1995 (posiblemente antes) y es muy común en sistemas de bus PCI no-Intel (como SPARC y PowerPC).
Básicamente se trata de un Forth nativo en una PROM, situada en la placa madre, que arranca al encenderse el ordenador. Examina algunos dispositivos locales y todas las direcciones del bus. Si existe un periférico con una dirección particular soportada por un dispositivo Open Firmware, el Forth de la placa madre "absorve" el driver desde la PROM sobre el periférico y lo compila a una forma ejecutable. Cuando esto se ha realizado con todos los dispositivos, el programa ya conoce la configuración completa del sistema y pasa a lanzar el sistema operativo (por ejemplo, Solaris o MacOS), tras lo cual lo configura. Todo este proceso lleva uno o dos segundos, entre el encendido y el lanzamiento del sistema operativo.
Pero lo realmente interesante es que, si el proceso se interrumpe, evita
que se ponga en marcha el sistema operativo, al tiempo que permanece en
Forth, el cual se puede usar de forma interactiva para diagnosticar el
hardware o cualquier otro problema. La razón del éxito del
Open Firmware de Sun radica en que permite integrar nuevos sistemas y periféricos
mucho más rápidamente usando esta via, por no mencionar la
facilidad para la diagnosis y reparación de los sistemas averiados.
(arriba)
(arriba)
(arriba)
En este número aparece un artículo sobre NEAR (Near-Earth Asteroid Rendezvous, es decir, Encuentro con un Asteroide Cercano a la Tierra), una sonda enviada por la NASA hacia el asteroide Eros, con la misión de obtener datos de este (y en el que después se decidió intentar, finalmente con éxito, el aterrizaje). Tal como relata Joe Anderson, citando como fuente al equipo encargado de administrar el proyecto (de la Johns Hopkins University), todos los instrumentos embarcados estaban programados en Forth, incluido un componente tan vital como los procesadores doblemente redundantes de manejo de datos y comandos (dual-redundant Command & Data Handling processors), encargados de enviar la telemetría a tierra, pasar los comandos enviados a los instrumentos, manejar la grabadora de datos, gestionar el control autónomo de la nave, etc. Según comenta John R. Hayes, uno de los integrantes del equipo desarrollador del proyecto, estaba claro que Forth era la elección obvia, no sólamente por su velocidad y economía en el consumo de recursos computacionales, sino por la disponibilidad de un chip idóneo: el RTX2010RH (RH es por "Radiation Hardened", es decir, resistente a la radiación; un requisito obligatorio en aplicaciones espaciales).
Pero lo curioso (y revelador) de esta historia es que, preguntado el señor Hayes de dónde sacó a los programadores (si eran físicos con interés en Forth, o programadores de Forth interesados por la física o la astronomía), confesó que fue él mismo quien eligió a gente de entre el personal y la instruyó en la programación en Forth para esta finalidad.
A continuación se muestra un cuadro con datos estadísticos del software de vuelo de la NEAR. Obsérvese, por ejemplo, el tiempo de desarrollo del software del ordenador de vuelo (124 meses/hombre, con el equipo de programadores más amplio), en comparación con el consumido por los instrumentos y subsistemas programados en Forth.
(arriba)
En el apartado de Noticias sobre Forth resulta interesante descubrir que este lenguaje ha desempeñado cierto papel en películas como Especies II, Tres Reyes, Strar Trek - La nueva generación o X-men. Concretamente, como software de una herramienta diseñada para fabricar una lente destinada a efectos especiales. Según el ingeniero encargado de su construcción, la parte software requirió prácticamente un par de semanas de desarrollo.
Por otro lado, Stephen Pelc (de MPE Ltd.) comenta que desarrolló un motor de juegos (en Forth, claro está) para un fabricante de teléfonos móviles, consiguiendo que los juegos tuvieran un tamaño inferior en un orden de magnitud al habitual.
En ¿Sabía usted que..? se cuenta que Keycorp usó Forth durante algunos años para programar su línea de tarjetas inteligentes (las típicas tarjetas con chip), a un coste de aproximadamente unos 2$ por tarjeta, lo que subía el precio final de las mismas hanta unos 5 a 7 dólares. Hasta que Sun se gastó 30 millones en promocionar su solución Javacard para programación de tarjetas inteligentes. Pese a que usar Javacard resultaba descabelladamente inapropiado (elevaba el coste por tarjeta hasta unos ¡30$!), su uso se extendió gracias a la gran reputación de Sun y la popularidad de Java. Los clientes de Keycorp ya no querían Forth, y esta se dió finalmente por vencida. ¡La simple superioridad técnica no podía competir con esto!
(arriba)
En este número se incluye una interesante entrevista a Tom Zimmer, personaje muy conocido en el mundo de Forth por sus diversos desarrollos de sistemas de este lenguaje en la modalidad de dominio público.
En la sección ¿Sabía usted que..? de este número se relata otro caso práctico de solución Forth a un problema peliagudo: el del aeropuerto King Khaled International Airport (Arabia Saudí). Diseñado a principios de los años 80 e instalado a mediados de esa década, estaba programado en FORTRAN y PLM. Los equipos eran nueve PDP 11/44s, cientos de ordenadores basados en el procesador 8086, y miles de sensores. Tras unos 100 años equivalentes de programador para desarrollar el código, este se mostró 10 veces más lento de lo estipulado. Sin embargo, AVCO/Textron consiguió una versión completa y rápida del sistema (escrito en Forth) en 18 meses reales (invirtiendo 30 años de programador).
(arriba)
(volver)