2 puntos por GN⁺ 2023-07-18 | 1 comentarios | Compartir por WhatsApp
  • Forth comenzó como un intérprete pequeño que Chuck Moore creó para reducir los largos flujos de compilación y tarjetas perforadas, y luego creció hasta convertirse en un sistema que absorbía incluso el editor, el sistema operativo y el compilador
  • La notación posfija (RPN), la pila de datos y las palabras (dictionary) no eran una sintaxis extraña, sino un diseño para reducir desperdicio y trabajo repetitivo en hardware con muchas limitaciones
  • El núcleo de Forth está en una estructura autoarrancable en la que incluso elementos como :, ;, IF, los comentarios y las variables pueden definirse y redefinirse dentro del propio lenguaje
  • Implementaciones como JonesForth, nasmjf, PlanckForth y sectorforth muestran que Forth puede comenzar con decenas o cientos de bytes, o con unas pocas primitivas, y expandirse hasta convertirse en intérprete, compilador, ensamblador o DSL
  • Los casos de naves espaciales, Open Firmware, Jupiter Ace, Canon Cat, Harris RTX2010 y GreenArrays muestran que Forth encaja fuertemente con el desarrollo interactivo, el código pequeño, la afinidad con el hardware y la computación de bajo consumo

Del mito de Usenet a la exploración de Forth

  • Dave Gauer organizó un recorrido personal sobre cómo descubrió Forth y cómo lo ubicó dentro de la historia de la computación, y esta página fue adaptada a partir de unas diapositivas de una presentación breve
  • Los grupos comp.* de Usenet en los años 90, en especial comp.lang.*, fueron un lugar importante para aprender y debatir sobre programación
    • También se menciona como ejemplo que el primer anuncio de Linux por Linus Torvalds apareció en comp.os.minix en 1991
    • A fines de los años 90, Perl tuvo un peso importante en la Web temprana como lenguaje para páginas dinámicas y procesamiento de formularios mediante CGI
  • Leyendas como los lenguajes de la familia Lisp conocidos en la época de Usenet, el combinador Y, The Little Schemer y The Story of Mel llevaron esa curiosidad hacia Forth
  • Al principio, Forth se presentaba como “un lenguaje tan flexible que puede cambiar el valor de los enteros”, y Chuck Moore quedaba en la memoria como una especie de “mad wizard” capaz de escribir cualquier programa con unas cuantas pantallas de código
  • La serie del blog de James Hague programming in the twenty-first century fue el impulso final para explorar Forth

RPN y la pila son solo el punto de partida

  • La primera impresión de Forth es la notación posfija o Reverse Polish Notation (RPN)
    • A diferencia de la notación infija habitual 3 + 4, Forth pone el operador después de los operandos, como en 3 4 +
    • El ejemplo de Forth 3 4 * 5 6 * + . imprime 42
    • En dc, el mismo cálculo se expresa como 3 4 * 5 6 * + p
  • La RPN permite evaluar expresiones anidadas en el orden deseado sin paréntesis
    • 3 4 * produce 12, 5 6 * produce 30, y el + final produce 42
    • En Forth, . extrae un valor de la pila y lo imprime
  • La calculadora HP-35 es un caso histórico importante para que la RPN se hiciera conocida fuera de la informática
    • A comienzos de los años 70, HP ya tenía calculadoras de escritorio potentes, y la HP-35 se presenta como el caso de llevar esa capacidad de cálculo a una calculadora de “bolsillo de camisa”
    • Las calculadoras HP eran famosas por la sintaxis RPN, que era eficiente pero algo críptica para quienes no estaban familiarizados con ella
  • La segunda característica es la pila de datos
    • Operaciones como PUSH, POP, SWAP y DUP también son palabras de Forth
    • Al ingresar números, estos se apilan, y los operadores toman valores de la pila, calculan y vuelven a colocar el resultado
  • La pila reduce la necesidad de poner nombres a valores intermedios
    • En muchos imperative language se necesitan nombres temporales como result2 o matched_part3
    • Esta forma de trabajar sin nombres también se conoce como implicit, tacit o point-free programming
    • Entender Forth solo como RPN y pila es insuficiente, pero sí es un punto de partida válido para comprender su origen histórico

Programación concatenativa, Joy y en qué se diferencia Forth

  • Al explorar Forth, aparece el concepto de programación concatenativa
    • Un ejemplo applicative es eat(bake(prove(mix(ingredients))))
    • Un ejemplo concatenative es ingredients mix prove bake eat
    • Las funciones se enumeran en orden, y el valor de cada etapa se pasa implícitamente a la siguiente
  • Joy es un caso representativo de concatenative language
    • Manfred von Thun se inspiró en la conferencia del ACM Turing Award de John Backus de 1977, “Can Programming Be Liberated from the von Neumann Style?”
    • En Joy, todas las funciones toman una pila como entrada y devuelven una pila como salida
    • Un programa es una lista de funciones que se lee de izquierda a derecha
  • Las quotation y combinator de Joy muestran una forma de cálculo sin variables
    • En JavaScript, [1, 2, 3, 4].map(n => n + 1) produce [2,3,4,5]
    • En Joy, se obtiene el mismo resultado con [1 2 3 4] [1 +] map
    • En Joy, [] es un mecanismo de quotation que puede contener no solo datos, sino también programas
  • Un combinator se trata como una función de orden superior que recibe funciones como entrada
    • map() es un ejemplo de abstracción del código repetitivo para recorrer listas
    • Los combinators I, K y S, y el cálculo SKI, aparecen como construcciones para explicar la computación universal
    • Solo con S y K ya se puede formar un sistema completo para computación universal
  • Forth también puede crear funciones de orden superior con execution token y la palabra EXECUTE
    • FOO EXECUTE ejecuta la palabra devuelta por la palabra FOO
    • Se pueden definir palabras combinatorias como MAP, FOLD y REDUCE
  • Forth y Joy se parecen en la sintaxis superficial, pero difieren en cómo interpretan las expresiones
    • En Forth, 2 3 + se lee como “apila 2 y 3, y luego súmalos”
    • En Joy, se lee como “la composición de las funciones 2, 3 y + es equivalente a la función 5”
    • Forth se parece más a un lenguaje que creció a partir de la interacción con el hardware que a uno centrado en principios abstractos de computación concatenativa

El camino por el que Chuck Moore creó Forth

  • En 1958, Chuck Moore usó Fortran e IBM 704 durante su etapa en el Smithsonian Astrophysical Observatory y MIT
    • En Forth, the Early years, Moore dice: “Compiling took 30 minutes...you got one shot per day”
    • También aparece una cita que describe al IBM 704 como una computadora de tubos de vacío que llenaba una habitación y que, en promedio, se averiaba aproximadamente cada 8 horas
  • Moore creó un intérprete simple que leía tarjetas que controlaban el programa para reducir las recompilaciones
    • Podía configurar distintas ecuaciones para varios satélites sin hacer recompile
    • El formato de entrada free-form era más confiable para que lo escribiera una persona que las columnas con formato de Fortran
    • Este sistema se convirtió después en el origen del sistema que más tarde sería llamado Forth
  • En 1961, en Stanford, Moore usó una Burroughs B5500 y escribió una aplicación matemática llamada CURVE
    • CURVE incluía un interpreter más sofisticado, data stack y operadores de control de flujo
    • Sus funciones correspondían aproximadamente a palabras de Forth como IF ELSE DUP DROP SWAP + - *
    • Al añadirse un parameter stack y la capacidad de definir nuevos procedures, empezó a aparecer una estructura más cercana a Forth
  • Hacia 1965, con la llegada de entornos de teletype, paper tape, timesharing e interactive terminal, Forth se volvió más interactivo
    • Se añadieron palabras como KEY, EMIT, CR, SPACE, DIGIT
    • Estas palabras convirtieron el sistema de Moore en un editor de programas, y el usuario podía editar programas desde dentro del propio programa
  • En 1968, en Mohasco, Moore trabajó con una IBM 1130 y le dio el nombre “FORTH”
    • La IBM 1130 tenía una configuración de 16 bits y 8 KB de RAM, y los nombres de archivo estaban limitados a 5 caracteres
    • El sistema de “fourth generation” de Moore pasó a ser FORTH por esa limitación de 5 caracteres
    • En este periodo se añadieron el return call stack y el word dictionary
  • El word dictionary con nombres de Forth funciona como la abstracción principal
    • : DOUBLE DUP + ;
    • : QUAD DOUBLE DOUBLE ;
    • Sin un return stack, después de ejecutar DOUBLE no sería posible volver al punto restante de QUAD

NRAO, portabilidad e indirect threaded code

  • A comienzos de los años 70, Moore escribió software de control de computadoras para radiotelescopios en el National Radio Astronomy Observatory
    • NRAO tenía una política de usar Fortran en minicomputers, pero a Moore se le permitió usar Forth con base en sus éxitos anteriores
    • En spectral-line observing se podían mostrar los spectra que se estaban recolectando y ajustar line-shapes mediante least-squares
    • Este trabajo impulsó el state-of-the-art de la reducción de datos online, y los astrónomos lo usaron para descubrir y mapear moléculas interestelares
  • Elizabeth “Bess” Rather adoptó Forth y escribió el primer manual de Forth en 1972
    • Más adelante cofundó FORTH, Inc junto con Chuck Moore
    • Hasta su retiro en 2006, siguió siendo una de las principales expertas y promotoras del lenguaje Forth
  • Forth fue portado a varias máquinas, entre ellas IBM 360/50, Honeywell 316, Honeywell DDP-116 y DEC PDP-11
    • La implementación de Forth para H316 fue programada en la propia computadora y se usó para crear otros Forth, por lo que se considera la primera implementación completa y autónoma
    • La PDP-11 es una minicomputer importante vinculada con la historia de Unix y del lenguaje de programación C
  • Detrás de la posibilidad de portarlo a varias máquinas estaba el indirect threaded code
    • Aquí, threaded code no tiene relación con concurrency ni con multi-threaded programming
    • Threaded code almacena una lista de direcciones de subrutinas en lugar de instrucciones de llamada a subrutina
    • Para ejecutar esa lista de direcciones se necesita un code interpreter
  • El indirect threaded code no almacena una lista de direcciones que apunten directamente al código, sino una lista de direcciones que apuntan a direcciones que apuntan al código
    • Gracias a esa segunda indirección, se puede tener un inner interpreter distinto para cada tipo de subrutina
    • En Forth, el outer interpreter es la parte con la que interactúa el usuario desde la terminal, y el inner interpreter ejecuta el resto de la palabra
  • En este punto, Forth ya iba más allá de un simple command interpreter y se había expandido a lenguaje interactivo, editor, sistema operativo y método de almacenamiento y ejecución de código
    • Se resumen características como postfix notation, orientación a stack, estilo concatenative, interpreted, alta adaptabilidad a la machine architecture y tamaño extremadamente compacto
    • Forth no fue un lenguaje diseñado de una sola vez en 1958, sino el resultado de cómo Moore lo fue haciendo crecer según sus necesidades y el nuevo hardware

Para entender Forth hay que implementar un Forth

  • En el consejo “To understand Forth, you have to implement a Forth”, la palabra importante es a Forth
    • Desde la perspectiva de Chuck Moore, un sistema Forth funciona mejor cuando está custom-tailored al sistema y a la tarea
  • Antes de trabajar con el código fuente de JonesForth, el autor escribió Assembly Nights para aprender fundamentos de assembly y del Linux ABI
    • JonesForth usa código fuente en assembly i386 escrito para el ensamblador GNU GAS
    • Es exclusivo de 32 bits y usa directamente el Linux system call ABI
    • El autor pasó cerca de un año portando JonesForth a una copia funcional con el ensamblador NASM, y ese port es nasmjf
  • Durante el proceso de portabilidad de nasmjf, aprendió cómo funciona un Forth indirect threaded tradicional
    • jonesforth.S de JonesForth es un único archivo que contiene la parte en assembly, y Richard W.M. Jones guía el flujo del interpreter con ASCII art y explicaciones
    • El autor escribió varios diagramas en ASCII art dentro del código fuente de nasmjf para ordenar su propia comprensión
  • La macro NEXT es el flujo clave que permite pasar a la siguiente palabra después de ejecutar una palabra
%macro NEXT 0
    lodsd     ; NEXT: Load from memory into eax, inc esi to point to next word.
    jmp [eax] ; Jump to whatever code we're now pointing at.
%endmacro
  • lodsd mueve un double word desde memory hacia eax y actualiza el puntero para que señale la siguiente posición
  • jmp [eax] transfiere la ejecución hacia el lugar al que se apunta en ese momento, y eso se convierte en el inner interpreter de esa subrutina
  • En el Forth tradicional existen básicamente code words y colon words
    • Una code word es una primitive escrita en machine code
    • Una colon word es una palabra normal escrita en el lenguaje Forth y ensamblada por el compilador :
    • Una colon word termina con EXIT, y EXIT maneja el return stack antes de continuar el flujo con NEXT
  • Forth está formado por piezas muy pequeñas que trabajan juntas para construir un sistema en ejecución
    • En niveles bajos se obtiene flexibilidad y simplicidad, pero en niveles altos puede sacrificarse la facilidad de comprensión

Las code words, colon words y el compilador funcionan sobre el mismo intérprete

  • SWAP, DUP y DROP muestran qué tan directamente pueden implementarse las primitivas de Forth en machine code
DEFCODE "SWAP",SWAP,0
    pop eax
    pop ebx
    push eax
    push ebx
NEXT
DEFCODE "DUP",DUP,0
    mov eax, [esp]
    push eax
NEXT
DEFCODE "DROP",DROP,0
    pop eax
NEXT
  • JonesForth usa el call/return stack de i386 como el parameter stack de Forth, así que implementa las operaciones de stack con pop y push nativos
  • nasmjf tiene 130 code words, y la mayoría existen por eficiencia
    • hay un mínimo teórico en la cantidad de machine-code words necesarias para un sistema Forth bootstrappeable
    • si se reduce demasiado el número de primitivas, el resto del código Forth puede volverse ineficiente y retorcido
    • A 3-INSTRUCTION FORTH FOR EMBEDDED SYSTEMS WORK de Frank Sergeant trata de un Forth de 3 instrucciones que solo requiere 66 bytes en Motorola MC68HC11
    • sectorforth es un Forth x86 de 16 bits que cabe en un boot sector de 512 bytes
  • un colon word es una forma de crear una nueva word como composición de words existentes
: SDD SWAP DROP DUP ;
  • SDD produce el mismo efecto que llamar SWAP DROP DUP en ese orden
  • desde la perspectiva del indirect threaded code, un colon word queda compilado como las direcciones del inner interpreter de tres code words
  • : y ; parecen sintaxis, pero en realidad son words de Forth
    • : toma el nombre de la nueva word y activa el compile mode
    • ; completa la nueva entrada del dictionary y desactiva el compile mode
    • el usuario puede reemplazar : con su propia definición para extender o cambiar Forth
    • la única sintaxis de Forth es el whitespace entre tokens de entrada
  • en Forth, compilar consiste en colocar en memoria direcciones de words o literales y código para hacer push
    • en normal mode, las words se ejecutan de inmediato
    • en compile mode, la dirección de la word se guarda en memoria
    • el mismo intérprete realiza tanto la ejecución como la compilación del código
  • incluso estructuras de control como IF...THEN pueden implementarse en el propio Forth
: IF IMMEDIATE ' 0BRANCH , HERE @ 0 , ;

: THEN IMMEDIATE DUP HERE @ SWAP - SWAP ! ;
  • que incluso un elemento tan fundamental como IF esté definido dentro del lenguaje es una base clave del título “The programming language that writes itself”
  • los comentarios anidados ( ... ) también están implementados en Forth dentro de jonesforth.f
    • incluso los comentarios se implementan dentro del lenguaje, y el usuario puede redefinirlos o añadir su propia forma de comentar
    • este ejemplo subraya que Forth casi no tiene sintaxis nativa

El dictionary y la redefinición crean extensibilidad

  • el dictionary de Forth tradicionalmente usa una linked list, y la coincidencia de words empieza desde la entrada más reciente
    • la definición más nueva de una word con el mismo nombre oculta la definición anterior
    • cualquier word puede redefinirse, incluso una definida inicialmente en assembly
    • las words ya compiladas guardan direcciones, no nombres, así que siguen apuntando a la dirección de la word anterior a la redefinición
  • en una definición nueva se puede llamar a la word anterior con el mismo nombre para extenderla
    • al crear una word recursiva, : oculta la word que se está compilando en ese momento del dictionary o la marca como inactiva
    • para llamarse a sí misma dentro de la word actual se necesita RECURSE
  • el ejemplo de la variable de manzanas, tomado y modificado de Thinking Forth de Leo Brodie, muestra la flexibilidad de Forth
    • VARIABLE APPLES crea la word APPLES, que al invocarse pone una dirección de memoria en el stack
    • 20 APPLES ! guarda 20 en esa dirección
    • APPLES ? obtiene el valor y lo imprime
    • Thinking Forth (PDF) está disponible gratis
  • incluso si hubiera que llevar por separado el conteo de manzanas rojas y verdes, no haría falta cambiar el código existente que usa APPLES
VARIABLE COLOR

VARIABLE REDS
: RED REDS COLOR ! ;

VARIABLE GREENS
: GREEN GREENS COLOR ! ;

: APPLES COLOR @ ;
  • la nueva APPLES también es una word que pone una dirección en el stack, así que se mantiene la forma de uso existente con APPLES ! y APPLES ?
  • lo único que cambia es que la dirección pasa a ser REDS o GREENS según el color de manzanas activo
  • desde la perspectiva de un lenguaje convencional, parece que una variable se convirtió en una función, pero en Forth no hay cambio conceptual a nivel del lenguaje, porque tanto las variables como las funciones son words que ponen o usan direcciones
  • incluso los tokens que parecen números pueden redefinirse como words del dictionary
: 4 12 ;
  • al ejecutar ." The value of 4 is " 4 . CR, se imprime The value of 4 is 12

Meow5 y Forth como “el camino de menor resistencia”

  • nasmjf, un port de JonesForth a NASM, no fue una recreación del proceso de Moore, sino más bien un ejercicio cercano a observar con detalle una “master copy” del resultado final
  • después, el autor realizó un experimento extremo de programación concatenativa llamado Meow5
    • Meow5 es un experimento donde todo el código siempre se concatena y se inlinea
    • es concatenativo porque usa el concepto de parameter stack, como Forth
    • fue un experimento mental llevado al extremo: qué pasaría si, en vez de guardar direcciones de llamada a funciones, se guardaran copias completas de cada función
  • el núcleo de Meow5 es hacer 100% inline de todas las words
    • parte de la inline expansion, una optimización común para evitar el pequeño overhead de llamar funciones
    • llamar una primitiva de una sola instrucción como DROP pasando por varios saltos parecía un desperdicio
  • Meow5 terminó como un “pequeño fracaso divertido”
    • el inline de machine code en sí funcionó bien, y el ejecutable ELF exportado también funcionó como se esperaba
    • el problema fueron los datos de strings: había que copiarlos cada vez o rastrear de forma compleja qué words usaban qué strings
    • se evalúa como mejor enfoque la word INLINE de Forth, que ofrece inline selectivo
  • la sintaxis de strings también volvió a confirmar el consejo de Moore
    • en Forth se usa la word ", así que se necesita un espacio, como en " Hello World."
    • Meow5 adoptó un estilo de quoting más natural como "Hello World." y secuencias de escape como \n y \"
    • esa decisión obligó a manejar excepciones para " en varias partes del tokenizer y del intérprete, reduciendo la pureza y la simplicidad
  • una vez que se empieza a seguir el camino de Forth, el resto parece “escribirse solo”
    • Forth es bootstrapping, metaprogramación y puede convertirse en OS e IDE/editor
    • eso lleva a la idea de que, al crear el intérprete más simple posible para una arquitectura de CPU completamente nueva, uno podría terminar usando algo muy parecido a Forth

Implementaciones pequeñas de Forth y usos reales

  • Forth puede definir más Forth dentro de Forth, y muchas implementaciones de Forth también incluyen assembler
    • Al final de JonesForth hay un stub de un assembler que funciona dentro de Forth
    • ;CODE actualiza el header para que el codeword apunte a código ensamblado en vez de a DOCOL
  • PlanckForth es un Forth binario de menos de 1 KB escrito a mano
    • Un binario ELF completo y una implementación funcional de Forth caben en menos de 1 KB
    • bootstrap.fs empieza con operadores crípticos al principio y unas cuantas centenas de líneas después se convierte en un Forth fácil de leer
  • Los casos de implementaciones pequeñas muestran la compresibilidad extrema de Forth
    • SmithForth es un Forth en código máquina escrito a mano por David Smith, presentado como un sistema Forth de 1,000 bytes y 1,000 líneas
    • sectorforth es un Forth de boot sector de 512 bytes
  • Forth se usa en plantas de energía, robótica, sistemas de rastreo de misiles, automatización industrial, lenguajes embebidos para videojuegos, bases de datos, contabilidad, procesadores de texto, gráficos, sistemas de cómputo, el boot loader Open Firmware y diversos procesadores y microcontroladores
  • Open Firmware es un caso importante surgido de la ingeniería de Sun Microsystems
    • Al estar basado en un lenguaje de programación interactivo, permite probar y hacer bring-up de hardware nuevo de manera eficiente
    • En el caso del Space Shuttle ESN, Open Firmware se presenta como una herramienta capaz de depurar hardware, software, drivers de plugins e incluso el propio firmware
  • Jupiter Ace fue una computadora doméstica británica de 1982 cuyo sistema operativo era Forth
    • El OS y la biblioteca de rutinas cabían en una ROM de 8 KB
    • Hay una cita de 1982 que afirma que el Forth integrado era “10 veces más rápido” que BASIC interpretado y requería menos de la mitad de memoria
  • Canon Cat tenía en 1987 un sistema operativo basado en Forth y metía el OS, la suite de oficina y el entorno de programación en 256 KB de ROM
    • Era un producto que implementaba en hardware y software la interfaz centrada en teclado y la filosofía de diseño de Jef Raskin
    • El procedimiento para entrar a la interfaz de Forth no parece ser el flujo de uso prioritario, pero si conoces el procedimiento se puede hacer con unas cuantas pulsaciones

Software espacial y Forth

  • Uno de los usos más interesantes de Forth es la exploración espacial
    • Las naves espaciales son costosas y difíciles o imposibles de reparar, así que la confiabilidad del software es crítica
    • La lista de proyectos de la NASA que usaron Forth es larga; el enlace original desapareció, pero hay copias en Wayback Machine y forth.com
  • El Space Shuttle Small Payload Accommodations Interface Module (SPAIM) fue un caso de uso de Forth
    • El equipo de desarrollo escribía rutinas en Forth en una PC, las descargaba y luego las probaba de forma interactiva
    • Hay una cita que dice que durante la misión STS-45 del Shuttle, el software de vuelo de SPAIM funcionó sin problemas
    • El sistema Forth de SPAIM permitía multitasking, cada task tenía su propio stack y una watchdog task vigilaba el estado de los stacks
  • El Space Shuttle Robot Arm Simulator es un caso en el que un programador desarrolló un dispositivo complejo en cinco semanas
    • Tenía que recibir comandos de un joystick de tres ejes y controlar un brazo de 50 pies de largo con seis articulaciones y seis sistemas de coordenadas
    • Se cita que el system tenía 14 process separados
    • También se cita que las pruebas de simulación fueron tan exhaustivas que, después de la instalación en sitio, no se cambió el algoritmo de executive control
  • El Shuttle Mission Design and Operations System (SMDOS) era software de control terrestre desarrollado por JPL
    • Durante la misión SIR-B, varias fallas de hardware se atendieron en sitio con modificaciones de software
    • Debido a problemas de antena y cambios de órbita, se necesitó una nueva estrategia de recolección de datos, y SMDOS se usó para mostrar planes acordes con las nuevas condiciones
    • Se perdió mucha información, pero con una estrategia de girar-capturar-girar-transmitir se recuperó el 20% de los datos
  • Harris RTX2010 era hardware Forth usado en muchas aplicaciones espaciales
    • Ejecuta Forth directamente
    • Dos hardware stack con profundidad de 256 words
    • Clock de 8 MHz y baja latencia
    • Características radiation-hardened
  • Rosetta y Philae se presentan como la primera misión en enviar una nave a orbitar un cometa y hacer descender un módulo de aterrizaje sobre su superficie
    • El Ion and Electron Sensor de Rosetta usa Harris RTX2010
    • El módulo de aterrizaje Philae usó dos RTX2010 en el CDMS y dos para controlar el ADS
    • Rosetta viajó de 2004 a 2014 hasta encontrarse con 67P/Churyumov-Gerasimenko
    • 67P tiene 4 km de ancho y orbita el Sol cada seis años y medio
  • Philae sufrió rebotes en la superficie por la baja gravedad debido a la falla de los arpones y del thruster de aterrizaje, pero fue lo bastante resistente como para completar el “80%” de su misión científica
  • También aparece el caso del parche al código del magnetómetro de Galileo en 1993
    • El magnetómetro tenía un RCA1802, 2 KB de RAM y 2 KB de ROM, y se programaba en Forth con un sistema de desarrollo basado en Apple II
    • Apareció un byte de memoria defectuoso en medio del código del instrumento y hubo que parchearlo para no usar ese byte
    • La persona citada escribió desde cero en Lisp un entorno de desarrollo Forth para ese instrumento y un simulador de hardware para generar el parche, y le tomó menos de tres meses a medio tiempo

Forth se parece más a una idea y un linaje que a una sola implementación

  • Forth se parece más a una idea con conceptos compartidos y linaje que a una única implementación representativa
  • Una de las razones por las que es difícil aprender Forth es que no existe una implementación única que represente de forma exclusiva el nombre “Forth”
    • Algunas formas tempranas de Forth son anteriores incluso al nombre “Forth”
    • El estándar de Forth continúa en los documentos de ANS Forth, y se mencionan el Forth 2012 Standard y el comité Forth200x
  • Las distintas variantes de Forth comparten conceptos y words comunes, pero los Forth especializados para ciertos fines tienen su propio vocabulario particular
  • Chuck Moore fundó Forth, Inc. en 1973 y desde entonces ha porteado Forth a varios sistemas, además de seguir creando sistemas nuevos
  • colorForth es un entorno posterior de Chuck Moore
    • Los colores del código fuente reemplazan parte de la puntuación estándar de Forth y determinan cómo se procesan los words
    • Se dice que los colores simplifican la semántica de Forth, aumentan la velocidad de compilación y también ayudan a Moore con su mala vista
    • colorForth incluye su propio sistema operativo de 63 KB
  • Moore considera que el software se vuelve complejo a medida que se le siguen agregando funciones, y que llega un punto en que nadie puede cambiarlo por miedo a consecuencias no deseadas
    • Esto lleva a la idea de que lo necesario es un programador dedicado que consagre su carrera a una sola aplicación, reescribiéndola una y otra vez hasta perfeccionarla

Afinidad mecánica, chips Forth, GreenArrays

  • Se menciona una cita donde Chuck Moore, desde la década de 1950, se ha opuesto a la complejidad del software y considera que sistemas operativos como Windows, UNIX y DOS son incomprensibles o innecesarios.
  • El autor explica la filosofía de Moore como Mechanical Sympathy.
    • Esta expresión proviene de una cita del piloto de Formula One Jackie Stewart, y en el contexto del software se usa en Why Mechanical Sympathy? de Martin Thompson.
    • Forth tiende a ser popular entre “personas de hardware”, como ingenieros eléctricos y diseñadores de sistemas embebidos.
  • Parece que la verdadera pasión de Chuck Moore está en el diseño de procesadores.
    • Harris RTX2000 y RTX2010 se presentan básicamente como chips de Moore.
    • Moore diseñó hardware desde el gate array Novix N400 de 1983, y el diseño mejorado se vendió a Harris y se convirtió en los chips RTX.
  • Moore diseña procesadores con OKAD, su propio software VLSI escrito en 500 líneas de Forth.
    • VLSI Design Tools (OKAD) explica que 500 líneas de colorForth proporcionan todo lo necesario para el diseño de chips.
    • OKAD es un conjunto de herramientas que incluye tecnología de compuertas lógicas, layout de circuitos, simulación del comportamiento eléctrico y exportación a GDSII.
  • Novix NC4000 es un motor de procesamiento ultrarrápido diseñado para ejecutar directamente instrucciones Forth de alto nivel.
    • Obtiene rendimiento al eliminar el assembly language convencional y el microcode interno.
    • La arquitectura de doble stack reduce en gran medida el overhead de implementación de subroutine.
  • Los chips GreenArrays se presentan en torno a la charla de Moore de 2013, “Programming a 144-computer chip to minimize power”.
    • Tiene 144 computadoras asíncronas en un solo chip.
    • Un core inactivo usa 100 nW, un core activo usa 4 mW y ejecuta a 666 Mips antes de volver al estado inactivo.
    • Cuando todas las computadoras funcionan a velocidad máxima, el consumo es de 550 mW, aproximadamente 0.5 W.
  • El documento GreenArrays Architecture enfatiza “NO CLOCKS”.
    • Explica que la generación y distribución del clock en computadoras convencionales consume mucha energía incluso en espera, sin hacer ningún trabajo.
    • GreenArrays se presenta no como un Multi-Core CPU, sino como un Multi-Computer System.

Simplicidad, eficiencia y el futuro de la computación de bajo consumo

  • El autor considera que tanto el software como el hardware han seguido avanzando hacia la acumulación de más capas de complejidad.
    • La computación en grandes centros de datos se percibe como barata o gratuita porque se paga indirectamente con presupuesto publicitario.
    • Se explica que lo que realmente se paga es la atención del usuario y sus datos personales.
  • Sostiene que no hay razón para seguir usando software cada vez más ineficiente y mal hecho, junto con requisitos de hardware cada vez más exigentes.
  • Los lenguajes similares a Forth pueden tener un futuro sólido en las siguientes áreas.
    • computadoras pequeñas y ubicuas
    • energía solar
    • VM fuertemente restringidas
  • El escalado de Dennard casi se detuvo alrededor de 2006.
    • La relación en la que transistors más pequeños permitían mayor velocidad y menor voltaje llegó a un estancamiento alrededor de 4GHz debido a fugas de corriente y calor.
    • The Free Lunch Is Over de Herb Sutter trata sobre cómo las mejoras en el rendimiento de CPU están pasando a hyper-threading y multicore.
  • Sutter considera que hay que rediseñar las aplicaciones para la concurrencia, o escribir código más eficiente y menos derrochador.
    • Dice que la optimización de rendimiento no será menos importante, sino más importante.
  • Hoy se puede comprar por unas pocas monedas un microcontroller mucho más potente que un IBM 704, y escribir sobre él un poderoso sistema Forth.
    • Un microcontroller puede funcionar con una batería de botón o un pequeño panel solar.
    • Continúa diciendo que nunca ha habido una época más asombrosa para la computación a pequeña escala.
  • Para entender Forth, hay que considerar la diferencia entre “simple” y “easy”.
    • Simple Made Easy de Rich Hickey se presenta como la charla que permitió expresar esa distinción.
    • Forth no es fácil y quizá no siempre sea divertido, pero sin duda es un lenguaje simple.
  • Growing a Language de Guy Steele es una charla que muestra cómo un lenguaje se construye a partir de primitivas.
    • La cita de Lisp sobre que, cuando una nueva palabra definida por el usuario parece una primitiva y una primitiva parece una palabra definida por el usuario, se convierte en un lenguaje más grande y sin costuras, también puede aplicarse a Forth.
  • La recomendación final es crear el lenguaje de programación perfecto para uno mismo.

1 comentarios

 
GN⁺ 2023-07-18
Comentarios en Hacker News
  • En cuanto conocí Forth, pensé que tenía que intentar hacer uno yo mismo, y por eso hice MiniForth en una semana hace dos años
    Estaba dirigido a la Blue Pill y al Arduino original, pero lo desarrollé con un compilador cruzado para poder probarlo en el host
    Me enganchó tanto que esperaba con ganas cada rato para trastear con él después del trabajo, y lo terminé en cinco noches de semana y un día del fin de semana
    Recomiendo muchísimo pasar por ese proceso; la única experiencia similar de revelación que tuve fue cuando conocí por primera vez los macros de Lisp (https://www.thanassis.space/score4.html#lisp)
    • Totalmente. En mi clase de arquitectura de computadores de primer año teníamos que hacer un proyecto final de tema libre para la LC-3, y como antes había jugado un poco con Forth en el mod RedPower 2 de Minecraft, pensé que implementarlo sería divertido
      Se comió casi todo mi tiempo libre de ese semestre, y un día vi el reloj y me di cuenta de que había pasado la noche en vela hasta que ya estaba amaneciendo
      Nunca he usado Forth de forma práctica en la vida real, pero la experiencia de construir uno desde cero de verdad se describe mejor como algo casi religioso
      Se sentía como la esencia pura de la programación de la que hablaba Fred Brooks: que los programadores, como los poetas, trabajan apenas un poco apartados de la materia pura del pensamiento, construyendo castillos en el aire solo con la imaginación, y que los programas son magia real donde, si escribes bien el conjuro, algo que antes no existía cobra vida en la pantalla
    • Estoy completamente de acuerdo. Hace muchísimo tiempo hice un compilador de Forth en ZX81 BASIC
      Pasó de tardar 19 segundos en imprimir 1000 números en pantalla a terminar casi al instante
      Y además me dejó una gran lección: vi el código máquina generado y pensé que era perfecto y que no podía mejorarse, pero al día siguiente volví y logré hacerlo muchísimo más rápido
  • Uno podría preguntarse: “¿Cómo que se escribe a sí mismo? ¿No solo significa que puedes escribir funciones?”
    Hasta cierto punto sí, pero Forth va más allá porque permite definir nuevas palabras y hacer que formen parte del propio lenguaje
    Estas palabras pueden usarse como operaciones integradas, e incluso pueden cambiar la manera en que funciona el lenguaje
    Como es un lenguaje extensible, también puedes definir nuevas estructuras de control o palabras que cambien la sintaxis, y esa flexibilidad no es común en otros lenguajes
    En ese sentido, Forth puede verse como un lenguaje que “se escribe a sí mismo”, porque permite al programador personalizarlo y extenderlo a un nivel muy fundamental
    También se parece al sistema de macros de Lisp: así como los macros de Lisp permiten crear nuevas estructuras sintácticas y lenguajes específicos de dominio mediante transformaciones en tiempo de compilación, las palabras de Forth también permiten extender la sintaxis y la funcionalidad
    • Suena genial, pero en casi 40 años trabajando como programador profesional, el problema nunca ha sido la sintaxis sino siempre la semántica
      Puede haber casos, como la multiplicación de matrices, donde escribir A = B + C * D; sea mejor que ir indicando una por una las funciones que hay que llamar, pero nunca me he encontrado con un problema así
      No sé si me falta imaginación, si esto solo sirve en ciertos dominios y yo nunca he estado en ellos, si la sintaxis de Forth es tan pobre que hay que ampliarla para que sea usable, o si a la gente simplemente le gusta personalizar lenguajes como quien tunea un auto
      No termino de entender por qué a la gente realmente le interesa esto
  • Uno de los proyectos de Forth más interesantes en este momento es Dusk OS, un sistema operativo de 32 bits escrito en Forth que incluye su propio compilador de C, y además se está portando a varias plataformas
    https://duskos.org/
    • No conozco bien DuskOS en sí, pero históricamente sí es cierto que Forth era “su propio sistema operativo”, aunque era bastante rudimentario comparado con lo que un lector moderno imaginaría como un sistema operativo
      Claro, puedes decir que para algo que corría en 8 KB de RAM no se podía pedir mucho, pero aunque ofrecía funciones básicas, históricamente casi no tenía drivers ni la mayoría de los conceptos de abstracción
      El código se cargaba desde el código fuente, así que era lento; el enlace se parecía más a cargar bloques en el orden correcto; y para cargar un programa nuevo, primero había que quitar el actual
      No sé si era mucho mejor que CP/M, que a menudo hacía un arranque en frío de la máquina al salir de un programa, aunque al menos CP/M sí separaba BIOS y BDOS
    • Se me había pasado esto. Justo estaba leyendo “Beyond the Collapse”, y sentí que con mis conocimientos de Lisp o APL/J y C sería difícil acercarme a la simplicidad de Forth a nivel de sistema operativo
      Pienso revisarlo sí o sí antes del próximo fin de semana
  • Mis primeros lenguajes de programación fueron ensamblador x86 y Forth. Mi padre estaba fascinado con Forth, y aprendí programación con él
    De adolescente hice varios sistemas Forth x86 para DOS, y al final llegué a crear “Third”, una implementación ANS compatible y bastante pulida: https://github.com/benhoyt/third
    Es bastante sorprendente que puedas tener un compilador de Forth completamente autoarrancable, incluso con ensamblador incluido, en apenas unos miles de líneas de código
    Hace poco también transcribí un artículo antiguo que escribimos en conjunto para la revista Forth Dimensions
    Las ideas de Forth siguen siendo buenas, pero la manipulación de la pila se vuelve tediosa rápido y además se hace muy difícil de leer
    Se nota en los ejemplos de código de https://benhoyt.com/writings/forth-lookup-tables/, especialmente en Search-Table. Poner nombres es difícil, pero parece que no ponerlos es todavía peor
    • Tal vez la manipulación de la pila se vuelve tediosa porque ni tú ni yo somos Chuck Moore
      Su código en general tiene muy poco desorden de pila. Por ejemplo: http://www.merlintec.com/download/color.html
    • Le eché un vistazo rápido al código fuente de Third y está interesante
      Veo que durante el bootstrap llama a kernel.com; me da curiosidad cómo construiste kernel.com
  • Charla relacionada de Chuck Moore: “Programming a 144 Computer Chip to Minimize Power” (2013)

https://www.youtube.com/watch?v=0PclgBd6_Zs
Así es como, al parecer, Forth impulsa computadoras de ultra bajo consumo: GreenArrays está enviando chips asíncronos de 144 núcleos, y solo requieren 7 pJ/inst de energía
Los núcleos inactivos no consumen energía (100 nW), y los núcleos activos ejecutan rápidamente con 4 mW (666 Mips) antes de quedar inactivos mientras esperan comunicación

  • “Siempre pensé que el tamaño y la velocidad solo les importaban a los amateurs. Pero, en el contexto moderno, solo hay tres parámetros que importan: potencia, potencia, potencia
    --Chuck Moore
    https://youtu.be/0PclgBd6_Zs?t=389
  • De verdad me pregunto si este tipo de estructura topológica no volverá en los próximos años
  • Un excelente libro de introducción es Starting Forth
    Tiene la ilustración más encantadora que he visto en un libro de texto
    [0] https://www.forth.com/starting-forth/
  • Hace mucho tiempo, cuando salió OS/2, un amigo me dijo que “los programas para OS/2 no se podían escribir en ensamblador, había que escribirlos en C”
    Como reacción a eso, hice Forth/2
    Era un compilador de Forth para OS/2, de código nativo con threaded code directo, escrito en ensamblador; Brian Matthewson escribió un excelente manual, y consiguió varias decenas de usuarios
    [1] https://sourceforge.net/projects/forth2/
  • Esto va un poco por otro lado, pero recuerdo haber leído la forma prototipo original de la presentación de este artículo
    Era básicamente igual al texto actual, pero con mucho menos texto y más espacios en blanco
    Lo menciono porque ese material también muestra la belleza del minimalismo en términos de tecnología de sitios web
    [0] http://ratfactor.com/forth/forth_talk_2023.html
    [1] http://ratfactor.com/minslides/
  • Me parece interesante que también exista un compilador de Forth en Rust. El material relacionado está en [1]
    Su uso todavía es algo poco claro[2], pero ya se había tratado aquí antes[3], y la implementación se ve sólida
    No es una máquina virtual Forth con REPL, pero es una impresionante implementación de máquina virtual
    Si FORTH es una máquina virtual, desde hace tiempo he pensado que podría ser la mejor opción cuando se necesita un sistema pequeño y eficiente capaz de manejar datos en streaming con un rendimiento cercano al bare metal
    También está el hecho de que no hay que pelearse con el sistema operativo
    Me da la impresión de que esto es, en esencia, hacer en una CPU estándar lo que hace un FPGA
    Aunque lo imagino como un sistema especializado donde no sea necesario crear todos los drivers uno mismo para conectarlo con el hardware requerido
    [1] https://docs.rs/rust-forth-compiler/latest/src/rust_forth_co...
    [2] https://docs.rs/fortraith/latest/fortraith/
    [3] https://news.ycombinator.com/item?id=23501474
  • También implementé otro Forth por mi cuenta
    No fue con la intención de copiar fielmente la idea original, sino que funciona de una manera algo distinta
    Como el artículo decía que uno podía encontrarse con Forth, dejo también mi implementación: https://github.com/loscoala/goforth
    La mayor diferencia es que, en esta variante de Forth, el texto fuente se convierte por completo en bytecode, y no existe un runtime en el sentido clásico de Forth
    Por eso es fácil traducir el bytecode a C
    Uso este Forth para generar código C, y luego incrusto ese código en otro software
    • Ese enfoque puede ser muy productivo e ingenioso, pero hay que tener siempre presente que este tipo de soluciones multilenguaje suele convertirse en un dolor de cabeza de mantenimiento a largo plazo
      Hay un proyecto open source realmente bueno que te permite entrenar el oído y la lectura a primera vista, pero está escrito en un lenguaje creado por su autor y ese lenguaje compila a JavaScript
      Configurar toda la toolchain es tan problemático que, aunque conozco bastantes bugs, ni siquiera me he animado a corregirlos
      https://sightreading.training/
      https://github.com/leafo/sightreading.training
      Este proyecto está escrito en un lenguaje llamado ‘Moonscript’: https://github.com/leafo/moonscript
      Moonscript compila a Lua, y Lua compila a JS
      Una locura. Una locura genial, eso sí, pero igual hizo que yo no terminara convirtiéndome en colaborador