REXX
De Wikipedia, la enciclopedia libre
REXX (REstructured eXtended eXecutor) es un lenguaje de programación desarrollado en IBM por Michael Cowlishaw del que existen numerosas implementaciones disponibles con código abierto. Es un lenguaje de programación estructurado de alto nivel diseñado para ser al mismo tiempo fácil de entender y fácil de leer. Hay intérpretes para REXX tanto comerciales como de código abierto para un amplio rango de plataformas y hay compiladores para los mainframes de IBM.
El nombre también se aplica a la familia de lenguajes relacionados con el lenguaje de programación REXX: el propio REXX (llamado en ese contexto REXX clásico o tradicional), Object REXX y NetREXX.
Tabla de contenidos |
[editar] Características
REXX tiene, entre otras, las siguientes características:
- tiene la cadena de caracteres como base
- no hay declaraciones
- no hay palabras reservadas (excepto en un contexto local)
- precisión numérica arbitraria
- aritmética decimal
- un gran conjunto de funciones (especialmente para procesado de cadenas y palabras)
- gestión automática de la memoria
- arrays asociativos
- acceso directo a las órdenes y facilidades del sistema
- manejo de errores sencillo
- herramientas de trazado y depuración dentro del intérprete
- acceso a la entrada y salida simplificado
REXX tiene solamente 23 instrucciones de significado bastante evidente para los angloparlantes (call, parse y select son unos ejemplos) con unos requerimientos mínimos de puntuación y formateo. Es esencialmente un lenguaje de formato libre con solamente un tipo de dato primitivo: la cadena de caracteres. Esta filosofía implica que todos los datos son visibles y que la depuración y el trazado se simplifican.
La sintaxis de REXX parece similar a la de PL/I, pero tiene menos notaciones; esto hace que el código sea más difícil de analizar por el intérprete o el compilador pero más fácil de usar para el programador.
[editar] Historia
REXX fue diseñado e implementado por vez primera como un proyecto personal de Mike Cowlishaw de IBM entre el 20 de marzo de 1979 y mediados de 1982, originalmente como un lenguaje de programación de 'scripting' para reemplazar los lenguajes EXEC y EXEC 2. Fue diseñado para ser un lenguaje de scripting o macros para cualquier sistema y como tal, se considera a REXX precursor de lenguajes como Tcl y Python. Además, Cowlishaw se centró en que estuviese orientado a las personas en lugar de orientado a los ordenadores e intentó que el lenguaje se mantuviese pequeño y manejable por ello ("Keep the language small" -"Mantén el lenguaje pequeño"- se leía en la pared sobre su escritorio).
La primera versión pública apareció en mayo de 1979 distribuida a través de VNET, la red interna de IBM y los primeros usuarios aparte del propio Cowlishaw fueron Ray Mansell (de Hursley en el Reino Unido) y Les Koehler (de Raleigh en Carolina del Norte) que contribuyeron al lenguaje. A finales de 1979 al menos había unos 70 ordenadores con una implementación del lenguaje.
Algunas versiones fueron distribuidas entre compradores seleccionados de IBM como el SLAC (Stanford Linear Accelerator Center) donde la capacidad de REXX de trabajar con aritmética decimal de precisión arbitraria fue bien recibida. Al ser descrito por primera vez en público en la conferencia SHARE 56 en Houston, Texas, en 1981, la reacción de los clientes de IBM, liderada por Ted Johnston de SLAC (parcialmente motivada por la aritmética de REXX), condujo a que se convirtiese en producto oficial de IBM en 1982 y se incluyese en 1983 como parte del sistema VM/CMS.
A lo largo de los años, IBM incluyó REXX en forma de intérprete o compilador en casi todos sus sistemas operativos desde los mainframes a los ordenadores personales (VM/CMS, VM/GCS, MVS TSO/E, AS/400, OS/2, VSE/ESA, AIX, CICS/ESA y PC-DOS) y ha hecho versiones disponibles para Novell Netware, Windows, Java y Linux.
La primera versión fuera de IBM fue escrita por Charles Daney en 1984/5. Otras versiones han sido también desarrolladas para Atari, Amiga, Unix (múltiples variantes), Solaris, DEC, Windows, Windows CE, PocketPC, MS-DOS, Palm OS, QNX, OS/2, Linux, BeOS, EPOC32, AtheOS, OpenVMS, OpenEdition, Macintosh y Mac OS X.
La versión de REXX para Amiga, llamada ARexx debida a Bill Hawes se incluyó con AmigaOS 2 y fue popular tanto para scripting como para control de aplicaciones. Muchas aplicaciones Amiga tienen "puertos ARexx" en ellas lo que permite controlar la aplicación a través de un "script" definido por el usuario.
Numerosas versiones gratuitas de REXX están disponibles. En 1992 aparecieron las dos versiones de código abierto más ampliamente utilizadas: REXX/imc del británico Ian Collier para UNIX y Regina del noruego Anders Christensen (posteriormente adoptada por el australiano Mark Hessling) para Windows y Linux. BREXX del griego Vasilis Vlachoudis es bien conocido para DOS, WinCE y PocketPC.
Microsoft decidió incluir Regina en todos sus Windows Resource Kits como lenguaje de scripting y continuó esta práctica hasta Windows 2000 mientras introducía sus propias aproximaciones al scripting a través de WSH (Windows Scripting Host) y VBA (Visual Basic for Applications).
En 1990, Cathy Dager de SLAC organizó el primer simposio REXX independiente que conduciría cuatro años después a la formación de la RexxLA (REXX Language Association). Los simposios se llevan a cabo anualmente.
La RexxLA promovió la aparición de un estándar ANSI para REXX así como de un borrador para un estándar de Object REXX.
En 1996, ANSI se publicó el estándar para REXX: ANSI X3.274–1996 “Information Technology – Programming Language REXX”.
Desde mediados de la década de 1990, existen dos variantes nuevas de REXX:
- NetREXX – que compila a bytecodes Java o es interpretado directamente.
- Object REXX – que es una versión orientada a objetos compatible con REXX.
REXX cumplió su vigesimoquinto aniversario el 20 de marzo de 2004, lo que se celebró en el decimoquinto Simposio Internacional de REXX organizado por la RexxLA (REXX Language Association) en Böblingen, Alemania, en mayo de 2004.
En el mismo decimoquinto Simposio Internacional de REXX, el 4 de mayo de 2004, IBM anuncia que retira Object REXX como producto y la intención de abrir el código fuente de Object REXX. Ante este anuncio, la RexxLA se ofrece a gestionar el futuro de Object REXX y nombra un comité para encargarse de la transición. El 12 de octubre de ese mismo año anuncia que transferirá el código a RexxLA para que se convierta en un proyecto de código abierto bajo la licencia Common Public License y el 29 de noviembre de ese mismo año se ha terminado de transferir todo el código excepto el código específico de la versión para OS/2, el IBM Resource Workshop (que permitía crear diálogos para Windows), Object REXX Workbench (IDE) y el paquete de funciones RxFTP. En febrero de 2005 aparece la primera versión pública de ooRexx (Open Object REXX) gestionada por David Ashley y Rick McGuire.
[editar] Variables
En REXX las variables no tienen tipo e inicialmente se les asigna como valor su nombre en mayúsculas. De este modo, el tipo de una variable puede cambiar con el uso dentro del programa. Como ilustra el siguiente código:
say hola /* HOLA <= La variable no tenía valor asignado */ hola = "25" /* Se le asigna la cadena "25" */ say hola || "0" /* 250 <= La variable es tratada como cadena */ say hola + 1 /* 26 <= La variable es tratada como número */ hola = "say 5 + 3" /* Se le asigna la cadena "say 5 + 3" */ say hola /* say 5 + 3 */ interpret hola /* 8 <= La variable es interpretada */ drop hola /* Se le desasigna el valor */ say hola /* HOLA */
REXX ofrece solamente un tipo de variable primitivo (la cadena) y un tipo de variable compuesta (que en REXX suele nombrarse precisamente de ese modo).
[editar] Variables simples
Los símbolos para las variables simples en REXX tienen como caracteres permitidos los típicos en casi todos los lenguajes de programación, pero nunca pueden tener un punto después del primer carácter dado que eso las convierte en una variable compuesta.
[editar] Como cadenas
REXX ofrece la operación de concatenación, la instrucción PARSE y un gran número de funciones para trabajar con cadenas por lo que muchas tareas con ellas resultan especialmente sencillas en este lenguaje.
Las cadenas están delimitadas por apóstrofos o comillas y al contrario que en otros lenguajes de programación interpretados, no existen las secuencias de escape ni la interpolación de variables; normalmente se utiliza la concatenación para conseguir los mismos efectos.
cadena = 'Una cadena delimitada por apóstrofos' cadena = "Una cadena delimitada por comillas" say "Hola.\a" /* Hola.\a <= No hay secuencias de escape */ say "$cadena" /* $cadena <= No hay interpolación de variables */ /* La siguiente cadena está delimitada por apóstrofos */ cadena = '"La vida es sueño", por Calderón de la Barca' /* La siguiente cadena está delimitada por comillas. Para escribir comillas dentro de la cadena, basta escribirlas por duplicado */ cadena = """La vida es sueño"", por Calderón de la Barca"
La concatenación de cadenas puede hacerse implícitamente al poner de forma contigua dos variables o explícitamente con el operador de concatenación (||):
uno = 'Una' dos = 'cadena' say uno dos /* Una cadena */ say uno||dos /* Unacadena */ say uno || ' 'dos /* Una cadena */
Cuando una cadena literal va seguida de "b" o "x" es tratada como una cadena binaria o hexadecimal:
/* El carácter para el tabulador horizontal: */ tab = '09'x /* en hexadecimal */ tab = '1001'b /* en binario */ campo_uno = 'Primero' campo_dos = 'Segundo' say campo_uno || tab || campo_dos
[editar] Como números
Las cadenas son tratadas como números dependiendo del contexto y cuando son números, pueden escribirse sin los delimitadores:
pi = 3.141592 seis = "6" say pi || seis /* 3.1415926 */ say pi + 6 /* 9.141592 */ numero_avogadro = 6.022e23
REXX ofrece la instrucción NUMERIC para establecer la precisión de los cálculos numéricos (con NUMERIC DIGITS), la forma de la salida de las cadenas como números (con NUMERIC FORM) y los dígitos significativos descartados a la hora de realizar las comparaciones (con NUMERIC FUZZ). Además las funciones digits(), form() y fuzz() permiten consultar la precisión, la forma y los dígitos significativos descartados en las comparaciones.
REXX ofrece una serie de funciones y operadores básicos para trabajar con números, pero carece de las funciones matemáticas básicas (raíz cuadrada, funciones trigonométricas...).
[editar] Como valores lógicos
Si una cadena vale uno o cero, entonces puede utilizarse como un valor lógico:
existe = "1" if existe & existe = 1 then say 'Esta cadena siempre se imprimirá' else say 'Esta cadena nunca se imprimirá'
[editar] Como estructuras de datos
Debido a la facilidades que ofrece REXX para trabajar con cadenas, resulta relativamente sencillo crear con una cadena una estructura de datos concreta (un número complejo, una matriz, los datos de un libro...):
/* Por convención, el programador puede tratar la cadena como la unidad imaginaria */ unidad_imaginaria = "0 1" /* Por convención, el programador puede tratar la cadena como la matriz identidad de orden tres */ matriz = "1,0,0;0,1,0;0,0,1" /* O, con otra convención distinta: */ matriz = "3,3,1,0,0,0,1,0,0,0,1" /* Por convención, el programador puede tratar la cadena como los datos de un libro */ delimitador = '00'x titulo = 'The Rexx Language'||, ': A Practical Approach to Programming'||, ' (Second Edition)' autor = 'Michael Cowlishaw' isbn = '0137806515' libro = titulo || delimitador || autor ||, delimitador || isbn
[editar] Variables compuestas
En REXX cualquier variable que incluya un punto tras el primer carácter de su nombre es una variable compuesta (compound variable en inglés). Los caracteres entre el primero y el primer punto (ambos están incluidos) son considerados el nombre de la variable y recibe el nombre de tronco (stem en inglés). Los caracteres posteriores al punto son la cola (tail en inglés). Así, por ejemplo, si tenemos el símbolo cv.libro.i
, cv.
es el tronco de la variable compuesta y libro.i
es la cola de la variable compuesta.
En REXX clásico, las variables compuestas no pueden pasarse como parámetros por referencia a una función, una función no puede devolverlas como resultado y no se incluye un modo de recorrerlas, copiarlas, ni ordenarlas.
var = 'Hola' /* Variable sencilla */ var. = 'Hello' /* Variable compuesta INDEPENDIENTE */ indice = 1 var.indice = 'Uno' var.2 = 'Dos' say var /* Hola <= La variable sencilla */ say var.1 /* Uno <= La variable compuesta */ say var.3 /* Hello <= La variable compuesta */ say uno.3 /* UNO.3 <= No inicializado */ drop var. say var.1 /* VAR.1 <= No inicializado */ say var /* Hola <= La variable sencilla */
[editar] Como arrays asociativos
Las variables compuestas en REXX funcionan esencialmente como arrays asociativos multidimensionales (a los arrays asociativos también se les llama, dependiendo del contexto, tablas de dispersión, hashes o diccionarios).
El siguiente ejemplo muestra el uso de una variable compuesta como array asociativo para manejar una pequeña agenda de teléfonos:
say 'Agenda de teléfonos' telefonos. = 'No se encuentra el número' nombre = 'Francisco Gómez de Quevedo y Santibáñez Villegas' telefonos.nombre = '1234567890' nombre = 'Miguel de Cervantes y Saavedra' telefonos.nombre = '0987654321' say 'Introduzca un nombre:' parse pull nombre say telefonos.nombre
Si el usuario introduce un nombre conocido tal y como está escrito, se imprimirá el número correspondiente. Si el nombre no es conocido ("Paco", por ejemplo) imprimirá el valor por defecto de la variable compuesta (es decir, "No se encuentra el número").
[editar] Como arrays
Las variables compuestas en REXX se usan con frecuencia como arrays con la peculiar convención de que se considera que el primer elemento tiene como índice 1 (al contrario que en otros lenguajes, en los que el primer elemento del array tiene como índice el 0) y el elemento con índice 0 se reserva para indicar el número de elementos del array:
array.0 = 3 array.1 = 'Uno' array.2 = 'Dos' array.3 = 'Tres' do i = 1 to array.0 say array.i end
[editar] Como arrays multidimensionales
Siguiendo convenciones similares, pueden construirse arrays de más de una dimensión como en el siguiente código:
matriz.1.1 = 1 matriz.1.2 = 0 matriz.2.1 = 0 matriz.2.2 = 1
[editar] Como estructuras de datos
Las variables compuestas en REXX pueden usarse para crear estructuras de datos más complejas (arrays de arrays asociativos, árboles binarios...):
/* Un número complejo */ unidad_imaginaria.re = 0 unidad_imaginaria.im = 1 /* Los datos de un libro */ libro.!titulo = 'The Rexx Language'||, ': A Practical Approach to Programming'||, ' (Second Edition)' libro.!autor = 'Michael Cowlishaw' libro.!ISBN = '0137806515'
[editar] Operadores
[editar] Operadores de concatenación
Los operadores de concatenación de cadenas en REXX son:
- (espacio) que concatena dejando un espacio entre las cadenas
- || que concatena sin dejar espacio entre las cadenas
- (yuxtaposición) que concatena sin dejar espacio entre las cadenas
Ejemplos de uso de estos operadores pueden encontrarse en la sección dedicada al uso de variables simples en REXX como cadenas.
[editar] Operadores aritméticos
Los operadores aritméticos binarios en REXX son los siguientes:
+ | suma | say 1 + 1 /* 2 */ |
|
- | resta | say 1 - 1 /* 0 */ |
|
* | producto | say 2 * 2 /* 4 */ |
|
/ | cociente | say 5 / 2 /* 2.5 */ |
siempre cociente real entre reales |
% | cociente entero | say 5 % 2 /* 2 */ |
|
// | resto | say 5 // 2 /* 1 */ |
diferente del módulo; puede dar un número negativo |
** | potencia entera | say 3 ** 2 /* 9 */ |
al contrario que en lenguajes como Perl, el exponente siempre es un número entero |
Los operadores aritméticos unarios en REXX son:
- - igual que "0 - numero"
- + igual que "0 + numero"
[editar] Operadores lógicos
Los operadores lógicos en REXX son:
- & y boleano
- | o boleano
- && o exclusivo
- \ no
[editar] Estructuras de control
REXX tiene solamente tres instrucciones básicas para construir todas las estructuras de control propias de la programación estructurada: DO/END, IF/THEN/ELSE y SELECT/WHEN/OTHERWISE/END.
La instrucción DO/END sirve para agrupar el código en bloques y para hacer bucles. Las otras dos instrucciones permiten hacer selecciones condicionales de código.
[editar] Bloques
DO cadena = 'Hola' say cadena END
[editar] Bucles
[editar] Bucles simples
veces = 5 DO veces say 'Esto se imprime' veces 'veces' END
DO FOREVER say 'Esto se imprime eternamente' END
[editar] Bucles controlados
DO i = 1 say i END /* Imprime indefinidamente: 1, 2, 3... */
limite = 100 DO i = 1 TO limite say i END /* Imprime los 100 primeros números naturales */
veces = 100 DO i = 1 FOR veces say i END /* Imprime los 100 primeros números naturales */
DO i = 10 TO 0 BY -1 say i END /* Imprime 10, 9, 8... */
[editar] Bucles condicionales
numero = 1 limite = 3 veces = limite - numero DO WHILE numero < limite numero = numero + 1 say 'Esto se imprime' veces 'veces' END
numero = 1 limite = 3 DO UNTIL numero > limite numero = numero + 1 say 'Esto se imprime' limite 'veces' END
[editar] Condicionales
IF numero = 1 THEN say 'El número es igual a 1'
IF numero = 1 THEN say 'El número es igual a 1' ELSE say 'El número es distinto de 1'
IF numero = 1 THEN say 'El número es igual a 1' ELSE IF numero = 2 THEN say 'El número es igual a 2' ELSE say 'El número es distinto de 1 y 2'
SELECT WHEN numero = 1 THEN say 'El número es igual a 1' WHEN numero = 2 THEN say 'El número es igual a 2' OTHERWISE say 'El número es distinto de 1 y 2' END
[editar] Tratamiento de errores y excepciones
En REXX es posible interceptar los errores y otras excepciones utilizando las instrucciones SIGNAL o CALL. El estándar ANSI establece que hay siete condiciones (ERROR, FAILURE, HALT, NOVALUE, NOTREADY, LOSTDIGITS y SYNTAX) y no permite definir nuevas excepciones ni generarlas (lo que sí es posible en Object REXX y NetREXX).
Este ejemplo funcionará hasta que sea interrumpido por el usuario o termine el millón de iteraciones del bucle:
signal on halt do i = 1 to 1000000 say 'El cuadrado de' i 'es' i**2 end exit halt: say 'El programa ha sido detenido por el usuario'
La siguiente tabla muestra las condiciones, da una somera idea de cuándo aparecen, establece con qué instrucciones pueden atraparse y el nivel del lenguaje en el que fueron introducidas.
ERROR | código de retorno (RC) positivo de una orden del sistema | SIGNAL y CALL | 3.5 |
FAILURE | RC negativo de una orden del sistema | SIGNAL y CALL | 3.5 |
HALT | programa detenido | SIGNAL y CALL | 3.5 |
NOVALUE | referenciada una variable sin valor asignado | SIGNAL | 3.5 |
NOTREADY | error de entrada o salida | SIGNAL y CALL | 4.0 |
LOSTDIGITS | pérdida dígitos significativos | SIGNAL | 5.0 |
SYNTAX | error de sintaxis o algún error no incluido en los anteriores | SIGNAL | 3.5 |
Cuando una condición es manejada por SIGNAL ON, las variables especiales SIGL y RC pueden ser analizadas para entender la situación. RC contiene el código de error de REXX y SIGL el número de línea donde ocurre el error.
[editar] El acrónimo REXX
[editar] Significado
En la primera especificación del lenguaje en 1979, Cowlishaw lo llamó simplemente "REX" porque le gustó cómo sonaba y justificó ese nombre como proveniente de "Reformed EXecutor".
La letra "X" adicional se añadió en 1982 para evitar problemas con marcas registradas cuando un estudio de IBM descubrió que había un producto comercial llamado Rex-80.
Normalmente se considera que REXX es un acrónimo y por lo general Cowlishaw y los documentos de IBM dicen que viene de "REstructured eXtended eXecutor", aunque también puede encontrarse como "Restructured EXtended eXecutor".
Debido al hecho de que el nombre original era igual a la palabra latina para "rey", existen muchas referencias a ello en el mundo que rodea al lenguaje: logos en forma de corona (Regina, Open Object REXX...), el nombre del intérprete Regina ("reina" en latín)...
[editar] Tipografía
En texto plano, Cowlishaw parece preferir Rexx, mientras que en los documentos de IBM y en la mayor parte de la web se usa REXX. El estándar ANSI utiliza la forma preferida por el comité de estandarización, que tiene letras mayúsculas pequeñas para las tres letras finales: REXX.
[editar] Pronunciación
Se pronuncia como "rex", sin hacer énfasis en la "x" final.
[editar] Bibliografía
- The Rexx Language: A Practical Approach to Programming (Prentice Hall, 1990), por Michael Cowlishaw, ISBN 0137806515
- Programming in REXX (McGraw-Hill, 1990), por Charles Daney, ISBN 0070153051
- REXX with OS/2, TSO, & CMS Features (M V S Training, 1999), por Gabriel Gargiulo, ISBN 189255903X
- Down to Earth Rexx (Perfect Niche Software, 2000), por William Schindler, ISBN 0967759005
- Rexx Programmer's Reference (Wiley/Wrox, 2005), por Howard Fosdick, ISBN 0764579967
[editar] Véase también
[editar] Enlaces externos
- Página del lenguaje REXX en IBM
- REXX Language Association (Asociación del lenguaje REXX)
[editar] Intérpretes
[editar] REXX clásico
- Regina: intérprete de código abierto (LGPL) para Linux, BSD, Windows, etc.
- REXX/imc: intérprete de código abierto (licencia no estándar) para sistemas Unix y Linux.
- BREXX: intérprete de código abierto (GPL) para DOS, Linux, Windows CE, etc.
- Reginald: intérprete gratuito para Windows.
- roo!: intérprete gratuito (Kilowatt Software) para Windows con extensiones orientadas a objetos.
- r4: intérprete gratuito (Kilowatt Software) para Windows.
- REXX para Palm OS: intérprete shareware (Jaxo Inc.) para Palm OS.
- Personal REXX: intérprete comercial (Quercus Systems) para Windows, OS/2 y DOS.
- S/REXX: intérprete comercial (Benaroya) para UNIX y Windows.
- uni-REXX: intérprete commercial (The Workstation Group Ltd.) para UNIX.
[editar] Object REXX
[editar] NetREXX
[editar] Grupos de noticias
[editar] Tutores
- El lenguaje REXX
- Rexx for everyone: una introducción por David Mertz para IBM developerWorks.
- Vladimir Zabrodsky's Album of Algorithms and Techniques for Standard Rexx
- Vladimir Zabrodsky's An Introduction to the Rexx Programming Language
- PLEAC-REXX: Programming Language Examples Alike Cookbook para REXX
- Rexx Frequently Asked Questions (FAQ): preguntas frecuentes de REXX
- Tutor introductorio de Rexx - SHARE, primavera 1997