Tests de tipo
Si en Prolog no existen declaraciones de tipo, ¿ como demonios
estamos seguros de que un argumento es de un tipo determinado ?.
La respuesta está en los tests de tipo.
Éstos són
predicados que (habitualmente) reciben un dato como argumento y fallan
si el argumento no es del tipo esperado.
Como ejemplo vamos a escribir el test de tipo para comprobar si un
argumento es una lista:
es_una_lista( [] ).
es_una_lista( [ _ | Resto ] ) :-
es_una_lista(Resto).
La lista vacía es una lista, y si no, [A|B] será una
lista si y sólo si B es una lista. En cuanto a A, nos trae al
fresco lo que valga, por eso usamos una variable anónima en
el código.
Ahora podemos comprobar el tipo de un argumento llamando al test de
tipo:
mi_predicado(Lista1,Lista2) :-
es_una_lista(Lista1),
es_una_lista(Lista2),
...,
Tests de tipo predefinidos
Existen predicados predefinidos para comprobar algunos tipos
básicos. Estos son:
| Predicado | Test |
| integer/1 |
Comprueba si su argumento es un número entero |
| float/1 |
Comprueba si el argumento es un número decimal |
| number/ |
Comprueba si el argumento es un número (entero o
decimal) |
| atom/1 |
Comprueba si el argumento es un término cero-ario
excluyendo las constantes numéricas |
| var/1 |
Comprueba si el argumento es una variable libre |
| nonvar/1 |
Comprueba si el argumento está instanciado |
| ground/1 |
Comprueba si el argumento es un término que no contiene
variables libres (está cerrado) |
Ejecución de los tests
La desventaja de los tests de tipo es que resulta necesario ejecutarlos.
Esto añade un tiempo extra de ejecución a nuestra
aplicación que no sirve para nada útil.
Sin embargo, esto es solamente una verdad a medias:
- La mayoría de los predicados no requieren test de tipo
como es el propio predicado que implementa el test de tipo. Todo
gracias a la unificación.
- Los compiladores más avanzados son capaces de suprimir los
test de tipo cuando pueden asegurar en tiempo de
compilación que el predicado no se llamará con
tipos inadecuados.
- Analogamente, algunos compiladores son capaces de insertar
automáticamente el test de tipo cuando al programador
"se le olvida" (es decir, siempre).
- Cuando la aplicación esta terminada y probada, el propio
programador puede suprimir los test de tipo si está seguro
de que no pueden producirse errores de tipo.
- El polimorfismo que aporta la ausencia de declaraciones de tipo
es deseable en muchas ocasiones. Por eso, los test de tipo
no siempre son necesarios.
En cualquier caso, el programador tiene libertad para decidir si es
necesario ejecutar tests de tipo en su programa.
Tests de tipo versus sublenguaje de tipos
La mayoría de los lenguajes tradicionales (imperativos)
incorporan un sublenguaje para la declaración de los
tipos. Se dice que es un sublenguaje porque no sigue la misma
sintáxis, ni dispone de los mismos recursos, que el propio
lenguaje de programación. Estos sublenguajes solamente
contemplan un tipado de tipo estructural, pero no de tipo
semántico.
Por ejemplo, es posible declarar el tipo de datos
Lista de números enteros, pero dificilmente podemos
declarar el tipo de datos Lista de números enteros ordenados
de menor a mayor que además son todos menores que cien.
A decir verdad, lo podemos declarar, pero no espere que el compilador
compruebe si las lista de su programa estan ordenadas o no.
Sin embargo, en Prolog esto sí es posible incluso
en tiempo de compilación. Hoy por hoy las técnicas
para conseguir esto están aún en investigación,
motivo por el que no va ha encontrar muchos entornos de desarrollo que
lo incorporen. Lo importante es ser consciente de que la ausencia de
sublenguaje de tipos no es una desventaja sino todo lo contrario.
Tipos paramétricos
También es posible escribir test de tipos paramétricos,
es decir, aquellos que dependen de otro tipo. Por ejemplo, para
evitar tener que definir un test de tipo para listas de números
y otro para listas de átomos, podríamos definir el tipo
"lista de X". La declaración de estos test de tipo requiere el
uso de predicados de orden superior (o metapredicados) que estudiaremos
posteriormente.
© Copyright 2000-2001
Angel Fernández Pineda.