Alias y Sobrecarga

Anuncio
Ambiente de Referencia
Aliases y Sobrecarga
Lenguajes de Programación I
Clausuras, Alias y Sobrecarga
Ernesto Hernández-Novich
<[email protected]>
c 2007-2010
Copyright Ambiente de Referencia
Aliases y Sobrecarga
¿Qué clase de valor tienes?
En general, en un lenguaje de programación se habla de
la clase de un valor.
Valores de Primera Clase
Se pueden asignar a variables.
Se pueden pasar como argumentos.
Se pueden retornar como resultados.
Todo tipo primitivo: números, caracteres, . . .
Valores de Segunda Clase
Se puede pasar como parámetro.
Subrutinas en la mayoría de los lenguajes.
Valores de Tercera Clase
Ninguna de las tres cosas.
Las etiquetas en la mayoría de los lenguajes.
Excepciones a esta clasificación agregan flexibilidad pero
agregan problemas interesantes en cuanto al alcance.
Ambiente de Referencia
Aliases y Sobrecarga
¿Y si el valor es una subrutina...?
Es habitual asociar un nombre a una subrutina para
invocarla – ¿y si usamos el nombre como un valor que
haga referencia a ella?
En lenguajes como Haskell, Lisp y Perl esto es posible –
las subrutinas son objetos de primera clase.
Es posible crear subrutinas con o sin nombre – cuando no
tienen nombre se llaman lambdas.
Es posible invocarlas de manera directa o indirecta.
Ambiente de Referencia
Aliases y Sobrecarga
Funciones que usan funciones como argumentos
Funciones de orden superior
Funciones que usan funciones como argumentos
Haskell
map (*2) [ 1, 3, 5, 7 ]
Perl
@pares = map { $_ * 2 } qw(1 3 5 7)
Lisp/Scheme
(mapcar (lambda (x) (* 2 x)) (1 3 5 7))
map y mapcar reciben una función como primer
argumento y una lista como segundo argumento, para
producir una lista.
En los tres casos, las funciones son anónimas, aunque no
tiene por qué ser así.
Ambiente de Referencia
Aliases y Sobrecarga
¿Qué tiene que ver con el alcance?
Si se tiene un lenguaje con Alcance Estático anidado y
Funciones de Primera Clase es posible que la referencia a
una función sobreviva al alcance donde fue definida.
En Perl
sub crea_contador {
my $base = shift;
return sub {
return $base++;
}
}
my $desde42 = crea_contador(42);
my $desde69 = crea_contador(69);
¿Qué va a pasar con $base?
¿Qué va a pasar cuando llamemos a las rutinas?
Ambiente de Referencia
Aliases y Sobrecarga
Depende de la vida de los objetos locales
La extensión de la vida de un objeto local puede ser
Ilimitada (como en los lenguajes funcionales) hasta que el
recolector de basura las recupere.
Limitada (como en los lenguajes imperativos).
Si los objetos locales son destruidos al final de cada
alcance, el ambiente de referencia estaría incompleto.
En lenguajes no-funcionales que quieren implantar
funciones de primera clase, es necesario un mecanismo
alternativo de almacenamiento para preservar el alcance.
Ambiente de Referencia
Aliases y Sobrecarga
Dos tipos de asociaciones
Asociación Profunda (Deep Binding) cuando el ambiente
de referencia es asociado con el cuerpo de la función al
momento de construirla.
Hacer un paquete con todas las variables alcanzables
estáticamente al momento de definir la función.
El cuerpo de la función tiene dicho paquete asociado, y se
denomina clausura (closure).
Al momento de ejecutarla, se usa ese paquete.
Asociación Superficial (Shallow Binding) cuando el
ambiente de referencia utilizado por el cuerpo de la
función es aquél vigente al momento de ejecución.
Alcance Estático vs. Alcance Dinámico.
Ambiente de Referencia
Aliases y Sobrecarga
Alias
Varios nombres para un mismo elemento en un alcance.
Aparecen en lenguajes que ofrecen apuntadores.
Existen lenguajes que incluyen el concepto de alias
explícitamente, por ejemplo en Perl:
$foo = 42; *bar = *foo;
print $bar;
(en este caso, alias entre variables, pero aplica para
arreglos, diccionarios, filehandles y funciones).
Tienden a hacer los programas más confusos.
Pueden impedir la generación de código óptimo.
Ambiente de Referencia
Aliases y Sobrecarga
Alias en C
void f o o ( )
{
i n t a , ∗pa ; / ∗ <− ∗ /
a
= 0;
pa = &a ;
∗pa = 4 2 ;
p r i n t f ( " % d % d \ n " , a , ∗ pa ) ;
}
Elaboración de a y *pa
pa
a
Ambiente de Referencia
Aliases y Sobrecarga
Alias en C
void f o o ( )
{
i n t a , ∗pa ;
a
= 0 ; / ∗ <− ∗ /
pa = &a ;
∗pa = 4 2 ;
p r i n t f ( " % d % d \ n " , a , ∗ pa ) ;
}
Accedemos via a
pa
a
0
Ambiente de Referencia
Aliases y Sobrecarga
Alias en C
void f o o ( )
{
i n t a , ∗pa ;
a
= 0;
pa = &a ; / ∗ <− ∗ /
∗pa = 4 2 ;
p r i n t f ( " % d % d \ n " , a , ∗ pa ) ;
}
*pa apunta a a – son alias.
pa
a
0
Ambiente de Referencia
Aliases y Sobrecarga
Alias en C
void f o o ( )
{
i n t a , ∗pa ;
a
= 0;
pa = &a ;
∗pa = 4 2 ; / ∗ <− ∗ /
p r i n t f ( " % d % d \ n " , a , ∗ pa ) ;
}
Modificamos via *pa.
pa
a
42
Ambiente de Referencia
Aliases y Sobrecarga
Alias en C
void f o o ( )
{
i n t a , ∗pa ;
a
= 0;
pa = &a ;
pa
∗pa = 4 2 ;
p r i n t f ( " % d % d \ n " , a , ∗ pa ) ; / ∗ <− ∗ / a
}
42 42
42
Ambiente de Referencia
Aliases y Sobrecarga
Sobrecarga
Ambiguedad uno a muchos
Nombre único para varios elementos en un alcance.
Se dice que el nombre está sobrecargado.
Casi cualquier lenguaje tiene algún nombre sobrecargado,
e.g. el + en C, el new en Java.
La sobrecarga puede estar establecida en el lenguaje
como consecuencia de su diseño, pero también puede
estar disponible al programador.
Sobrecargar funciones.
Sobrecargar operadores.
Ambiente de Referencia
Aliases y Sobrecarga
Sobrecarga de Funciones
Algunos lenguajes (C++, Java) tienen mecanismos para
sobrecargar nombres de subrutinas.
Mismo nombre, pero diferente número o tipo de
argumentos.
La firma de cada subrutina debe ser diferente.
La firma se analiza para determinar cuál es la función
particular que debe invocarse.
Ambiente de Referencia
Aliases y Sobrecarga
Sobrecarga de Operadores
Algunos lenguajes (C++, Perl, Fortran90) permiten
sobrecargar operadores aritméticos con funciones
definidas por el usuario.
Típicamente se asocia a un método de una clase para
agregar esa carga semántica al mismo símbolo.
Definir una clase Complex para números complejos.
Definir el método Complex add_complex(Complex)
para sumar un número complejo a una instancia.
Asociar dicho método al símbolo + del lenguaje para poder
escribir cosas como
a Complex;
b Complex;
c Complex;
c = a + b
// c = a.add_complex(b)
Ambiente de Referencia
Aliases y Sobrecarga
Cuando otras cosas parecen sobrecarga
Algunos lenguajes (Haskell) permiten definir funciones en
las cuales los tipos a recibir son arbitrarios siempre que su
uso sea consistente.
Esto es útil para definir funciones genéricas que pueden
operar con argumentos que cumplan con las restricciones
Ya vimos la función map.
Su primer argumento es una función.
Su segundo argumento es una lista.
map opera sin problemas siempre y cuando la función
pasada como argumento, pueda operar sobre objetos
como los que contiene la lista.
Esto no es sobrecarga, sino polimorfismo paramétrico
(que estudiaremos después). Sólo existe una función que
opera sobre diferentes tipos.
Descargar