10.1 FORTRAN.
10.1.1 Historia.
FORTRAN fue el primer lenguaje de programación de alto nivel en ser ampliamente usado.
Su primer desarrollo corresponde al año 1957, donde se usó el IBM 704 como el computador base. En esa época, la utilidad de cualquier LP de alto nivel era una cuestión discutida por los programadores formados en lenguajes ensambladores. LA objeción más seria tenía que ver con la eficiencia en la ejecución del código compilado desde LP's de alto nivel.
Como resultado de esto, el diseño de las primeras versiones de FORTRAN estaba fuertemente orientado a la eficiencia en la ejecución.
El éxito de la primera versión FORTRAN y su dependencia de características orientadas a la eficiencia en la ejecución en el IBM 704, llegaron a ser posteriormente un problema.
La primera definición standard del lenguaje surge en 1966, y una revisión importante a ese standard, hecha en los 70's llegó al surgimiento de FORTRAN 77, que continuó con la tradición de atribución estática a los datos.
La revisión actual del standard, FORTRAN 90, cambia radicalmente el enfoque, permitiendo datos dinámicos. Además, incorpora los conceptos de obsolescencia y desaprobación, como indicaciones de características que pueden omitirse en futuras revisiones del standard, un alejamiento radical de la mayoría de los standard, que requieren compatibilidad con versiones previas.
10.1.2 Sexo sin fronteras.
FORTRAN es generalmente implementado usando tecnología tradicional de compiladores. Un editor de texto es lo que se usa para crear un programa, un compilador FORTRAN traduce el programa a una forma ejecutable, un linker es usado para juntar subprogramas, el programa principal y bibliotecas de rutinas run-time y formar un programa ejecutable, y finalmente un paso de ejecución ejecuta el programa traducido.
Un programa FORTRAN consiste de un programa principal y una serie de subrutinas. El siguiente es un programa trivial típico:
$edit papaya.for
PROGRAM PAPAYA INTEGER I I=2 IF (I .GE. 2) CALL IMPRIMA STOP END SUBROUTINE IMPRIMA PRINT *, "Sexo sin fronteras" RETURN END
$fortran papaya.for
$execute
Sexo sin fronteras
10.1.3 Breve ojeada al lenguaje
El diseño de FORTRAN se centra en el objetivo de la eficiencia en la ejecución. Las estructuras del lenguaje generalmente son simples, y puede que gran parte del diseño no sea elegante, pero la eficiencia de ejecución es conseguida.
Cuando se habla de FORTRAN, tal vez sea conveniente considerar FORTRAN 77 y FORTRAN 90 como lenguajes diferentes. FORTRAN 90 agrega características modernas al manejo de datos y al control, para darle la potencia de lenguajes como C y Pascal.
Un programa FORTRAN consiste de un programa principal y un conjunto de subprogramas, cada uno de los cuales es compilado separadamente de los otros, siendo los programas traducidos linkeados a su forma ejecutable final durante el proceso de loading.
Cada subprograma es compilado a un segmento de código y registro de activación, estáticamente atribuido. No hay atribución de almacenamiento en ejecución, todo es hecho (atribución) antes que la ejecución comience, aunque FORTRAN 90 cambia el modelo de ejecución para permitir almacenamiento dinámico.
FORTRAN suministra apenas un conjunto restringido de tipos de datos: cuatro tipos de datos numéricos (entero, real, complejo y real doble precisión), datos Booleanos (llamados logical), arreglos, strings de caracteres, y archivos.
FORTRAN suministra un extenso conjunto de operaciones aritméticas y funciones matemáticas, lo que refleja la orientación del lenguaje hacia la ingeniería y la computación científica.
Se puede usar archivos secuenciales y de acceso directo y hay algunas facilidades de E/S y especificaciones de formato.
La gran debilidad de FORTRAN 77 radica en sus limitadas facilidades para estructuración de datos, esencialmente restringidos a arreglos y strings de caracteres de longitud predeterminada. No hay mecanismos para definir tipos nuevos o abstracciones de datos. El único mecanismo de abstracción lo constituyen los subprogramas (procedimientos y funciones).
Como se dijo antes, FORTRAN 90 introduce el concepto de desaprobado (deprecated), tal que si el comando IF es considerado obsoleto, será eliminado de versiones standard posteriores del lenguaje. Ya que la mayoría de las características dependientes de la máquina de FORTRAN 66 son hoy desaprobadas, para la próxima revisión del lenguaje, FORTRAN deberá ser un lenguaje moderno.
Este lenguaje ha sido concebido para ambientes batch. No posee características especiales para apoyar la construcción de programas grandes, más allá de la compilación separada de subprogramas.
Un ejemplo:
El siguiente programa realiza la suma de los elementos de un vector.
Los blancos son ignorados, de modo que se pueden agregar libremente para mejorar la legibilidad (por ejemplo indentar las anidaciones), no obstante, muchos programadores comienzan la escritura del comando en la columna 7.
1 |
2 |
3 |
4 |
5 |
6 |
7 |
||
1 |
P |
ROGRAM SUPERPALTA |
||||||
2 |
PARAMETER (TAMMAX = 99) |
|||||||
3 |
REAL A(TAMMAX) |
|||||||
4 |
1 |
0 |
READ(5, 100, END = 999) K |
|||||
5 |
1 |
0 |
0 |
FORMAT(I5) |
||||
6 |
IF(K .LE. O .OR. K .GT. TAMMAX) STOP |
|||||||
7 |
READ *, (A(I), I=1, K) |
|||||||
8 |
PRINT*, (A(I), I=1, K) |
|||||||
9 |
PRINT*, 'SUM=', SUM(A, K) |
|||||||
10 |
GO TO 10 |
|||||||
11 |
9 |
9 |
9 |
PRINT "ESTAMOS LISTOS" |
||||
12 |
STOP |
|||||||
13 |
END |
|||||||
14 |
C |
A |
Q |
U |
I |
SUBPROGRAMA SUMADOR |
||
15 |
F |
UNCTION SUM(V, N) |
||||||
16 |
REAL :: V(N) !Declaración en nuevo estilo |
|||||||
17 |
SUM = 0.0 |
|||||||
18 |
DO 20 I=1, N |
|||||||
19 |
SUM = SUM + V(I) |
|||||||
20 |
2 |
0 |
CONTINUE |
|||||
21 |
RETURN |
|||||||
22 |
END |
10.1.4 Data objects.
FORTRAN suministra 4 tipos de dato numéricos:
![]() | Entero |
![]() | Real |
![]() | Real doble precisión |
![]() | Complejo |
También considera un Boolean (llamado logical).
Los arreglos, strings de caracteres, y archivo son los únicos tipos de datos estructurados.
"Data objects" primitivos.
![]() | Variables y constantes. |
Los nombres de variables tienen un largo de 1 a 6 caracteres (a 31 en FORTRAN 90), comenzando con una letra, y permitiendo letras y dígitos (y _ en FORTRAN 90).
FORTRAN es insensible al tipo de letra; PRINT, pRint, PRint, ... , se refieren al mismo nombre.
Originalmente los programas FORTRAN se escribían sólo con mayúsculas, pero la política actual es mezclar mayúsculas y minúsculas, como en otros lenguajes.
Los primeros FORTRAN, ignoraban los caracteres en blanco, pero en FORTRAN 90 son significativos.
En FORTRAN 77 las tres líneas siguientes representan lo mismo:
DØ 20 I = 1,20
DØ20I=1,20
D Ø 2 0 I = 1 , 2 0
Pero a continuación hay un error en FORTRAN 90:
DO I = 1,20
. . .
ENDDO
!Falta un espacio entre END y DO.
Las variables no necesitan ser declaradas en forma explícita; la siguiente declaración es válida:
REAL A, B, SUM DOUBLE PRECISION Q, R LOGICAL :: T
La declaración de T muestra la sintaxis de FORTRAN 90 para las declaraciones.
Si no aparece una declaración explícita, una convención basada en el primer carácter del identificador de la variable determina su tipo.
I->N : Integer otros : real
Esta convención puede ser cambiada en un subprograma comenzando la definición con una sentencia IMPLICIT.
IMPLICIT INTEGER(A-Z)
El comienzo de un subprograma provoca la suposición de tipo integer para todas las variables no declaradas en forma explícita.
La declaración:
IMPLICIT NONE
anula todas las declaraciones implícitas de variables (en FORTRAN 90) y detecta como un error el uso de una variable que no ha sido declarada.
![]() | Tipos de datos numéricos. |
Los tipos numéricos integer, real y double-precision (real) en general se representan directamente usando representaciones numéricas del hardware. El tipo complex es representado como un par de números reales, almacenados en un bloque de dos palabras..
![]() | Variables tipo puntero. |
FORTRAN 77 no incluye el uso de variables tipo puntero, pero FORTRAN 90 si:
INTEGER, POINTER ::P
Lo que indica que p es un puntero a un entero.
Tipos de datos estructurados.
![]() | Arrays. |
Los rangos de los subíndices deben declararse en forma explícita, ya sea en una sentencia DIMENSION donde el tipo del componente se declara en forma implícita o declarando el array y el tipo de componente.
Ejemplo:
REAL M (20), N(-5:5) DIMENSION I(20, 20)
Si se omite el límite inferior para el subíndice se supone que es 1.
Los subíndices se usan para seleccionar los componentes de un array, usando la misma sintaxis que para las llamadas a funciones.
Ejemplo:
M(3) o N(I+2)
A diferencia de la mayoría de los lenguajes, los arreglos en FORTRAN se almacenan por columnas. No se almacenan descriptores con el array; si se necesita, debe ser almacenado separadamente.
![]() | Strings de caracteres. |
En FORTRAN se pueden declarar variables de strings de caracteres de longitud fija. Por ejemplo:
CHARACTER 5*10, T*25 CHARACTER (LEN=7) U
S y T son variables que contienen string de caracteres de largo 10 y 25 respectivamente, y U es un string de 7 caracteres en FORTRAN 90.
Representación del almacenamiento.
La representación secuencial del almacenamiento es crítica en las definiciones de las declaraciones COMINO y EQUIVALENCE. (ambas obsoletas en FORTRAN 90). [COMMON se discutirá más adelante].
La declaración EQUIVALENCE permite que más de una variable, simple o subindicada, se refiera a la misma ubicación de almacenamiento.
Por ejemplo:
REAL X INTEGER Y EQUIVALENCE(X, Y)
Esta declaración especifica que los nombres de variables simples X e Y deben ser asociados con la misma ubicación de almacenamiento. El valor almacenado en esa ubicación puede ser recuperado o modificado a través de cualquiera de los identificadores, X o Y. Esta característica, claramente lleva a potenciales errores.
![]() | Inicialización. |
Para inicializar datos estáticos, se usa una instrucción DATA. Esta sentencia se ve así:
DATA X |1.0|, Y|3.1416|, K|20|
X,Y y K deben ser variables locales, es decir, deben tener almacenamiento estático asociado que pueda ser inicializado al comienzo de la ejecución del programa.
Tipos definidos por el usuario.
FORTRAN 77 no tiene mecanismos para la creación de tipos usuario. Todos los tipos están predefinidos en el lenguaje.
En FORTRAN 90, existe el comando TYPE. Por ejemplo, para generar strings de longitud variable, se puede definir un tipo VSTRING:
TYPE VSTRING INTEGER :: SIZE CHARACTER(LEN=20) :: LEN END TYPE VSTRING
Las declaraciones son similares a otras declaraciones FORTRAN 90:
TYPE(VSTRING) :: MYSTRING
y % se usa como selector:
MYSTRING%SIZE O MYSTRING%LEN
10.1.5 Control de secuencia.
FORTRAN tiene un conjunto limitado de estructuras de control. Algunos dejan natos su ancianidad, por el hecho de ser derivados de aquellos antiguos momentos en que lo que se exigía era una ejecución eficiente.
Expresiones.
![]() | Sentencias. |
Asignación: variable = expresión
Condicional: if (expr) labelneg, labelcero, labelposit if (expr) sentencia if expr_test then else ...
Iteración: DO loop_control block de sentencias FORTRAN 90 END DO
DO label init_var = init_value, final_value, increment
Sentencia nula: CONTINUE
Control de subprogramas:
CALL nombre_subprograma(lista de parámetros)
Los programas finalizan con la sentencia RETURN.
![]() | Construcciones peligrosas. |
GOTO label
GOTO computado
GOTO(n1, n2, n3, ... ,nm), I
GOTO asignado
ASSIGN 21 TO K GOTO K
![]() | E/S. |
READ 200, N, (M(K), K=1, 7) 200 FORMAT(8I5) O
READ "(8I5)" N, (M(K), K=1,7)
Campo | Tipo de Datos | Ejemplo |
Iw | Integer | IS = 12345 |
Fw.d | Fijo(real) | FG.2 = 123.56 |
Ew.d | Exponencial(real) | E 10.2 = -12.34 E + 02 |
w.X | Skip | salta w carácteres |
Aw | Character | AG = abcdef |
"literal" | Constante | "abcdef" |
Manejo de excepciones:
READ (UNIT=2, FMT=200, END=50, ERR=90) N, (M(K), K=1, 7)
10.1.6 Subprogramas y administración de almacenamiento.
Subprogramas function.
Permiten el retorno de un sólo valor de tipo numérico, lógico o carácter.
Subprogramas Subroutine.
Retorna los resultados mediante el cambio en sus parámetros o en variables no locales en bloques COMMON.
Sentencia Function.
Una función cuyo valor puede ser computado en una sola expresión aritmética o lógica puede ser definida de esta forma, local a un subprograma particular y colocada antes de la primera sentencia ejecutable de ese subprograma.
Ejemplos:
SUBROUTINE SUB1(A, B, C) (A, B, C, Parámetros formales.)
REAL FUNCTION MIPROG(A, B, C)
FN(X, Y)=SIN(X)**2 - COS(Y)**2
Administración de almacenamiento.
Las referencias en FORTRAN son locales, o globales, no hay niveles intermedios de referencia no local antes de FORTRAN 90.
![]() | Ambientes locales. |
Consiste de las variables y arreglos declarados al comienzo de cada subprograma. Como se implementa FORTRAN normalmente, el ambiente local es retenido entre llamadas porque el registro de activación tiene su almacenamiento atribuido en forma estática como parte del segmento de código.
Sin embargo la definición del lenguaje no requiere la retención del ambiente local a menos que se incluya el comando SAVE dentro del subprograma. SAVE indica que el ambiente local completo debe ser retenido entre llamadas. Si se especifica SAVE A, X; sólo las variables A y X deben ser retenidas.
![]() | Ambientes COMMON. |
Un bloque COMMON es un bloque de almacenamiento que puede contener los valores de cualquier número de variables simples y arreglos. [continúa en 10.1.7]
FORTRAN 90 introduce el concepto de con la sentencia CONTAINS:
SUBROUTINE SUBRUT_EXTERNA ... CONTAINS SUBROUTINE INTERNA_1 ... SUBROUTINE INTERNA_2 ... SUBROUTINE INTERNA_3 ...
Así, las subrutinas internas INTERNA_1, INTERNA_2 o INTERNA_3 pueden ser referenciados en SUBRUT_EXTERNA, tal como en Pascal.
FORTRAN 90 también incluye recursividad:
RECURSIVE FUNCTION FACTORIAL(X) RESULT(RESULT_VAL)
La cláusula RESULT que contiene la variable retornada por el procedimiento es necesaria, para estas ambigüedades. Ej:
FACTORIAL = X * FACTORIAL(X-1) ¿llamada recursiva o valor local?
![]() | Parámetros en subprogramas. |
La transmisión de parámetros es uniformemente por referencia. Los parámetros reales pueden ser variables simples, literales, nombres de arreglo, variables con subíndice, nombres de subprograma o expresiones (aritméticas o lógicas).
Los resultados de los subprogramas FUNCTION son transmitidos por asignación, dentro del subprograma, al nombre del subprograma. El nombre del subprograma actúa como una variable local dentro del subprograma, y el último valor asignado antes del retorno, es el valor devuelto.
10.1.7 Abstracciones y encapsulamiento.
El último mecanismo de abstracción en FORTRAN 77 está dado por los subprogramas. FORTRAN 90 agrega módulos y tipos de datos.
Los bloques COMMON pueden ser usados para aislar datos globales a sólo unos pocos subprogramas que necesiten esos datos. Ejemplo:
COMMON /BLK/X, Y, K(25)
declara un bloque COMMON llamado BLK, que contiene las variables X e Y y al vector K. Suponiendo que X e Y son reales, y K es entero, el bloque ocupa 27 unidades de almacenamiento.
Si dos subprogramas, SUB1 y SUB2 contienen la misma declaración anterior, entonces BLK es accesible desde ambos.
Sin embargo, la estructura COMMON permite otras posibilidades:
Si sólo el nombre de un bloque COMMON (que es realmente un identificador global, las variables y nombres de arreglos son locales al subprograma al cual aparece el contenido), aparece, es solamente el bloque el que está siendo compartido, no los identificadores.
Por ejemplo, si el subprograma SUB1 contiene:
COMMON /BLK/U, V, I(S), M(4, 5)
También 27 unidades de almacenamiento, con los mismos tipos.
Sin embargo, las asignaciones involucran un conjunto completamente diferente de identificadores, lo que es válido siempre y cuando la longitud total del bloque y el tipo de estructura se mantenga.
10.1.8 Evaluación del lenguaje.
Ya no es tan popular como alguna vez lo fue, pero todavía es el lenguaje elegido por mucha gente que trabaja en computación científica.
Algunos casos en que la eficiencia de FORTRAN no se discute:
![]() | Integración numérica |
![]() | Dinámica de fluidos |
![]() | Soluciones de raíces de ecuaciones complejas |
![]() | Cálculos con matrices reales |
Ya que el lenguaje está en evolución, algunas limitaciones antiguas son poco importantes. Ya no es necesario rotular sentencias, debido a que hay estructuras de control que permiten la animación de múltiples comandos.
Las definiciones de tipo están basadas en la semántica tipo Pascal, y se introduce almacenamiento dinámico y variables tipo puntero; los nombres pueden ser más largos.
No obstante, todavía (para algunos) tiene un cierto "aire" de antigüedad.