next up previous contents
Next: La importancia de los Up: Lenguajes funcionales Previous: Lenguajes funcionales   Contents


La estructura de los lenguajes funcionales

Véase la expresión que define la función dimension:

  dimension :- (f, datom)

    if Atómica?(f)   then datom(f)
    else if Suma-o-Resta?(f) then
      DimAd( dimension( PrimerOperando(f), datom ),
             dimension( SegundoOperando(f), datom ) )
    else if Producto?(f) then
      DimProd( dimension( PrimerOperando(f), datom ),
               dimension( SegundoOperando(f), datom ) )
    else
      DimCoc( dimension( PrimerOperando(f), datom ),
              dimension( SegundoOperando(f), datom ) )

Interesa examinar la forma de las expresiones que ocurren a la derecha del símbolo :-. Véase que:

Lo anterior sugiere cierta similitud en el comportamiento de los nombres y las variables. En particular, ambos pueden denotar funciones que son aplicables a un conjunto de argumentos.

Esta similitud es aún más amplia, puesto que ambos pueden denotar también resultados de aplicaciones de funciones. Esto es claro para las variables, como en el caso de f, que, en general denota el resultado de la aplicación de un constructor de fórmulas.

Sucede lo mismo para los nombres. Aunque no hayan sido usados con ese sentido en nuestro caso de estudio, podrían darse, por ejemplo, definiciones como:

  1 :- sucesor(cero)
  2 :- sucesor(sucesor(cero))
  ...

que asociarían la representación corriente (con dígitos) a las expresiones dadas por la definición inductiva de los naturales con los constructores cero y sucesor.

De hecho, el uso de nombres es el mecanismo a través del cual una expresión arbitrariamente compleja puede ser referenciada sin necesidad de mostrar su estructura interna. Es, por tanto, una facilidad de abstracción en la formulación de expresiones.

La diferencia entre nombre y variable reside en que éste representa una expresión sobre cuya forma no se hacen hipótesis, es decir, "<una expresión cualquiera">. Cada nombre está asociado, por el contrario, a una expresión específica.

Estas consideraciones iluminan aspectos parciales de la estructura y el sentido de las expresiones usadas (a la derecha de :-):

A partir de estas expresiones primitivas pueden formarse otras más complejas, que, como éstas, se interpretan como definiciones y aplicaciones de funciones.

La definición del conjunto de estas expresiones, se completa usando inducción de una manera informal:

  <expresión> ::= <variable> |
                  <nombre>   |
                  ( <variable>,...,<variable> ) <expresión> |
                  <expresión> ( <expresión>,...,<expresión> )

Se definen expresiones atómicas (variables y nombres) y otras compuestas que se llamarán abstracciones funcionales y aplicaciones.

Nótese que la denominación abstracción funcional se asocia a las expresiones que definen funciones. Esto no esun mero refinamiento de la terminología.

Efectivamente, considérese una expresión sencilla como:

  4 + 2

Usando la abstracción funcional puede construirse una expresión de la cual la anterior sea un caso particular, haciendo, por ejemplo:

  (x) 4 + x

La nueva expresión da una forma más general, de la cual pueden obtenerse, por aplicaciones convenientes, la expresión original además de otras. El cambio de constantes por argumentos es una técnica de generalización corriente también en la práctica de la programación.

Este concepto resultará de utilidad más adelante.

Es interesante analizar con más cuidado la sintaxis dada, tratando de determinar el tipo de construcciones que ella autoriza. En particular, considérese el caso en que se desea definir una función. Corresponde a una expresión de la forma de abstracción funcional:

  ( <variable>, ... , <variable> ) <expresión>

En particular, es, obviamente, admisible que contenga un único argumento nominal, como en:

  (g) <expresión>

Ahora <expresión> puede ser reemplazada por cualquiera de sus formas válidas. Su significado será, de acuerdo a lo dicho, denotar el correspondiente de g en la función que se está definiendo.

Una de las posibilidades admitidas es que <expresión> sea reemplazada por otra abstracción funcional. Esto debe interpretarse como que el resultado de una función puede, a su vez, ser otra función.

Por ejemplo:

  (g) (x) <expresión>

Ahora está dicho que la imagen de g será una cierta función de x. Está por darse, todavía, la definición de esta última.

En particular, g también puede ser considerada como una función, a su vez. Esto no es una novedad, puesto que una variable denota en principio una expresión genérica y, de hecho, así se usó datom en dimensión.

Entonces puede entenderse:

  (g) (x) g (g (x))

La función definida sobre g le hace corresponder otra función que dado otro argumento x, aplica g a éste dos veces (twice, en inglés).

Ahora es posible asociar un nombre a esta función:

  twice :- (g) (x).g (g (x))

y calcular la imagen en twice de una función conocida, por ejemplo la raíz cuadrada (sqrt):

  twice (sqrt) :- (x) sqrt (sqrt (x))

donde aparece claro que la aplicación de twice a una función es otra función. Ésta puede aplicarse, a su vez, a un cierto valor, como en:

  twice (sqrt) (16)

cuyo resultado, salvo error u omisión, debería ser 2.

Varias conclusiones deben obtenerse:

Lo anterior permite simplificar la estructura de las expresiones del lenguaje: en la formulación de la forma general de las abstracciones funcionales y aplicaciones no es necesario denotar una cantidad indeterminada de argumentos. Apenas uno es suficiente para todos los casos:

  <expresión> :- <variable> |
                 <nombre>   |
                 ( <variable> ) <expresión> |
                 <expresión> ( <expresión> )

Estas expresiones pueden interpretarse usando un único concepto: el de función. Éstas pueden aplicarse entre sí y servir para definir a otras con plena libertad. Así lo autoriza la sintaxis.

El lector atento podrá argumentar que esta libertad es excesiva y posiblemente la crítica sea aceptable.

En efecto, hay expresiones permitidas cuyo sentido es oscuro, si no existente. Véase por ejemplo:

  5 (8)

que es un caso de aplicación donde función y argumento efectivo son nombres, pero que carece de sentido puesto que el primero no admite ser aplicado a ningún argumento, y también:

  sucesor (sucesor)

donde el argumento efectivo no es un natural, como debiera esperarse.

El problema es importante, y constituye la principal motivación para la introducción del concepto de tipo en los lenguajes.

Por supuesto, existen lenguajes funcionales con tipos, aunque no serán tratados en este desarrollo. Como consecuencia, la formación de expresiones con sentido exigirá la aplicación de una disciplina (no formalizada) adicional a las reglas de sintaxis de los lenguajes que se definan.

Sin embargo, la generalidad de la construcción de expresiones del lenguaje tiene importantes ventajas. En particular, si se reinterpreta el término función como programa se tendrá entonces que, en estos lenguajes, los programas pueden ser, con toda generalidad, argumentos de otros programas y pueden producir, también, otros programas como resultado.

Esta caracterización es, efectivamente, adecuada y se justificará plenamente en la siguiente sección, donde quedará de manifiesto su utilidad.


next up previous contents
Next: La importancia de los Up: Lenguajes funcionales Previous: Lenguajes funcionales   Contents
Cesar Ballardini
2003-10-14
Hosted by www.Geocities.ws

1