Está en la página 1de 106

Contenidos Generales

Valores y Tipos Variables y Abstracciones


actualización
Tipos Primitivos Tiempo de Vida de una variable Parámetros
Tipos Compuestos Enlace y Ámbito Mecanismos de Paso de
Control de Tipos Alcance y Visibilidad Parámetros
Equivalencia de Tipos Alcance Estático y Dinámico Ordenes de Evaluación
Principio de Completitud de
Tipos
Sistemas de Tipos
Sobrecarga, Polimorfismo y
Conversiones de Tipos

UTN
FRRe
https://www.youtube.com/watch?v=7MAeSbiLRPo
UTN
FRRe
UTN
FRRe
Valores
Llamaremos valor a algo que pueda se evaluado,
almacenado, incorporado a una estructura de datos,
pasado como argumento a un procedimiento o función,
retornado como resultado de una función etc.

Abstracción de
Valores Valores Referencias a
Punteros procedimiento
primitivos compuestos variables
y función

UTN
FRRe
Tipos
Un tipo es un conjunto de valores.

 Cuando decimos que v es un valor del tipo T, significa


simplemente que v  T.

 Cuando decimos que una expresión E es del tipo T,


significa que el resultado de evaluar la expresión E
dará un valor de tipo T.

 Deben exhibir un comportamiento uniforme bajo


operaciones asociadas a ese tipo.
◼ {23, verdadero, Lunes} No
◼ {verdadero, falso} Si
◼ {..., -2, -1, 0, 1, 2, ...} Si

UTN
FRRe
Tipos Primitivos

 Los tipos primitivos son aquellos que


están compuestos por valores atómicos
y por lo tanto no pueden ser
descompuestos en valores más simples.

UTN
FRRe
Tipos primitivos
 Valor_de_verdad
{verdadero, falso}

 Entero
{..., -2, -1, 0, 1, 2, ...}

 Real
{..., -1.0, ..., 0.0, ..., 1.0, ...}

 Carácter
{..., ‘a’, ‘b’, ..., ‘z’, ...}

UTN
FRRe
Tipos primitivos

 Tipo Enumerado
Meses {ene, feb, mar, abr, may, jun,
jul, ago, sep, oct, nov, dic}

data Color = Rojo | Verde | Azul


data Bool = True | False

 Tipo Subrango
28..31

UTN
FRRe
Cardinalidad

 Escribiremos #S para significar el número


de valores distintos en S.

Ejemplo:

◼ #valor_de_verdad = 2
◼ #meses = 12
◼ #enteros = 2 x maxint + 1 (en Pascal)

UTN
FRRe
Tipos Compuestos
 Un tipo compuesto (o tipo de datos
estructurado) es un tipo cuyos valores están
compuestos o estructurados a partir de valores
más simples.

◼ Tuplas
◼ Registros
◼ Arreglos
◼ Conjuntos
◼ Strings
◼ Listas
◼ Árboles
◼ Archivos secuenciales
◼ Archivos directos

UTN
FRRe
Tipos Compuestos:
Producto Cartesiano 1

type Fecha : record


m : meses;
d : 1..31;
end;
El tipo Fecha tiene el siguiente conjunto de valores:
{ene, feb, ..., dic} x {1, 2, 3, ..., 31}.

372 pares: (ene, 1) (ene, 2) ... (feb, 1) ... (dic, 31).

UTN
FRRe
Tipos Compuestos:
Producto Cartesiano 2

S x T = { (x,y) / x  S; y  T}
S T

u v a b c

Cardinalidad:

UTN
FRRe
Tipos Compuestos:
Producto Cartesiano 3
Los componentes de las tuplas son tomados de un mismo S:

(n veces)
n
S = S × S × ... × S

La cardinalidad estará dada por #(S ) = (#S)


n n

Si n = 0
n
#S = 1 Unit = { () }

Se corresponde con el unit de ML y void de algol-68 y C.


Unit no es un conjunto vacío, contiene una única tupla
que no contiene ningún componente.

UTN
FRRe
Tipos Compuestos:
Unión Disjunta
S + T = { izq x / x  S}  {der y / y  T}

S T

u v a b c

Cardinalidad:

UTN
FRRe
Tipos Compuestos:
Registros discriminados
type
TipoDato = (Num, Fech, Str);
Fecha = record D, M, A: Byte; end;
Ficha = record
Nombre: string[20]; (* Campo fijo *)
case Tipo: TipoDato of (* Campos variantes *)
Num: (N: real); (* Si es un número: campo N *)
Fech: (F: Fecha); (* Si es fecha: campo F *)
Str: (S: string[30]); (* Si es string: campo S *)
end;
var
UnDato: Ficha;

UnDato.Nombre := 'Nacho';
UnDato.Tipo := Num;
UnDato.N := 3.5;
Writeln('Ahora el tipo es numérico, el nombre es ', UnDato.Nombre);
Writeln('Campo N: ', UnDato.N);

UTN
FRRe
Tipos Compuestos:
Registros discriminados 2
Supongamos que se desea
almacenar datos de Soltero
personas en las que se
contempla el Estado Civil, Casado Conyuge Fecha
para el cual se guardará ApyNom Edad Estado

distinta información si es Viudo


soltera, casada, Fecha
divorciada o viuda. Divorciado

type
EstadoCivil = (ecSoltero, ecCasado, ecViudo, ecDivorciado);
Fecha = record D, M, A: byte; end;

Persona = record
ApyNom: string[20]; (* Campos fijos *)
Edad: integer;
case Estado: EstadoCivil of (* Campos variantes *)
ecSoltero: ();
ecCasado: (conyuge: string[20]; FBoda: Fecha);
ecViudo, ecDovorciado : (FFin: Fecha);
end;
UTN
FRRe
Tipos Compuestos:
Unión Disjunta 4
var
V1, V2, V3, V4, V5: Variant;
I: Integer;
D: Double;
S: string;

begin
V1 := 1; { integer value }
V2 := 1234.5678; { real value }
V3 := 'Hello world!’; { string value }
V4 := '1000’; { string value }
V5 := V1 + V2 + V4; { real value 2235.5678}
I := V1; { I = 1 (integer value) }
D := V2; { D = 1234.5678 (real value) }
S := V3; { S = 'Hello world!' (string value) }
I := V4; { I = 1000 (integer value) }
S := V5; { S = '2235.5678' (string value) }
end;

UTN
FRRe
Tipos Compuestos:
Unión Disjunta 5
 El compilador realiza las conversiones de tipos de acuerdo a las
siguientes reglas.

UTN
FRRe
Tipos Compuestos:
Unión Disjunta 6
Se pueden definir tipos compuestos que tengan círculos y
rectángulos como valores constitutivos:

data Forma = Circulo Float | Rectangulo Float Float

area :: Forma -> Float


area (Circulo r) = pi * r * r
area (Rectangulo base altura) = base * altura

UTN
FRRe
Recreo mental!
Imagina que tienes
1000 botellas de jugo,
una de ellas contiene
un líquido súper
fuerte y de sabor
amargo.
Cómo saber cuál es la
que contiene el
líquido amargo con el
menor número de
sorbos posibles?

UTN
FRRe
Tipos Compuestos:
Mapeo

type
color = (rojo, verde, azul);
pixel = array [color] of 0..1;

pixel = color → {0, 1}


0 0 0 0 1 1 1 0 0 1 1 0
rojo verde azul rojo verde azul rojo verde azul rojo verde azul

0 0 1 0 1 0 1 0 1 1 1 1
rojo verde azul rojo verde azul rojo verde azul rojo verde azul

UTN
FRRe
Tipos Compuestos:
Mapeo

bool pixel[3];

pixel = {0, 1, 2} → {T, F}


F F F F T T T F F T T F
0 1 2 0 1 2 0 1 2 0 1 2

F F T F T F T F T T T T
0 1 2 0 1 2 0 1 2 0 1 2

UTN
FRRe
Tipos Compuestos:
Mapeo

Supongamos m: S → T es una función de S en T

El conjunto de todas las funciones posibles de S → T :

S → T = {m / x  S  m(x)  T}

UTN
FRRe
Tipos Compuestos:
Mapeo. Ejemplo

Si consideramos a S = {u, v} y T = {a, b, c}.

S→T
S T
{u → a, v → a} {u → b, v → a} {u → c, v → a}
{u → a, v → b} {u → b, v → b} {u → c, v → b}
u v a b c {u → a, v → c} {u → b, v → c} {u → c, v → c}

Cardinalidad:

UTN
FRRe
Tipos Compuestos:
Mapeo 3
function par (n: Integer) : Boolean;
begin
Par := (n mod 2 = 0);
end;

Esta función implementa un mapeo particular definido de


Integer → Boolean

{0 → true, 1 → false, 2 → true, 3 → false, ...}

UTN
FRRe
UTN
FRRe
Tipos Compuestos:

UTN
FRRe
Tipos Compuestos:
Tipos Recursivos. Ejemplos 2

UTN
FRRe
Tipos Compuestos:
Tipos Recursivos. Listas

 Se considera un tipo recursivo a aquel que se compone de


valores del mismo tipo y se define en términos de si mismo.

Lista_enteros = nil Unit + cons (Entero x Lista_enteros)

{ nil }
 {cons (i, nil) / i  Entero }
 {cons (i, cons(j, nil)) / i, j  Entero }
 {cons (i, cons(j, cons(k, nil))) / i, j, k  Entero }
 ...

data [a] = [] | a : [a] en Haskell

UTN
FRRe
Tipos Recursivos. Arboles
Árbol binario polimórfico:

data Tree a = Hoja a | Rama (Tree a) (Tree a)

Nodo
Nodo Rama
Hoja

Rama
1
(Rama (Hoja 3) (Hoja 2)) 3 2
(Hoja 1)
UTN
FRRe
Tipos Recursivos. Arboles 2
Árbol binario polimórfico:

data Tree a = Vacio | Rama (Tree a) a (Tree a)

Árbol
Nodo Rama
vacío

(Rama
(Rama (Rama Vacio 24 Vacio) 15 (Rama Vacio 27 Vacio))

10
(Rama Vacio 18 (Rama Vacio 4 Vacio))

)
UTN
FRRe
Tipos Compuestos:
Tipos Recursivos. Arboles. Ejemplo

 Como será el árbol?


(Rama (Hoja [1,2,3]) (Hoja []))

 Ejemplo: encontrar todas las hojas de un arbol

hojas :: Arbol a -> [a]


hojas (Hoja h) = [h]
hojas (Rama izq der) = hojas izq ++ hojas der

UTN
FRRe
UTN
FRRe
UTN
FRRe
Control de Tipos

 Para qué se definen los tipos en los


lenguajes de programación?

UTN
FRRe
Data types
 Data types are present in programming
languages for at least three different
reasons:
◼ At the design level, as support for the
conceptual organization (effectively
controllable comments);
◼ At the program level, as support for
correctness (operaciones coherentes);
◼ At the translation level, as support for the
implementation (acceso directo a memoria).

UTN
FRRe
Control de Tipos

 En qué momentos puede realizarse el


control de tipos?

UTN
FRRe
Control de Tipos. Momentos

Estático
Ada, C, C++, C#, JADE, Java, Fortran, Haskell, ML,
Pascal, Scala

Dinámico
Groovy, JavaScript, Lisp, Lua, Objective-C, PHP, Prolog,
Python, Ruby, Smalltalk, Tcl

UTN
FRRe
Control de Tipos 3
Control de
Function par (n: integer): boolean;
Tipos Estático
Begin
Par := (n mod 2 = 0)
End;

Control de
Function par (n); Tipos Dinámico
Begin
Par := (n mod 2 = 0)
¿Qué ocurre en la
End;
llamada:
par (´a´)?
UTN
FRRe
Control de tipos. Analogía “A helpful analogy to understand
the value of static typing is to look at
it as putting pieces into a jigsaw
puzzle. In a statically typed
language, if a piece has the wrong
shape, it simply won't fit. In a
dynamically typed language, all the
pieces are 1x1 squares and always
fit, so you have to constantly
examine the resulting picture and
check (through testing) whether it's
correct.”
UTN
FRRe
Equivalencia de Tipos
1. Considere una operación que espera un operando del tipo T.
2. Suponga que en realidad el operando en cuestión es de tipo T’.
3. El lenguaje debe chequear si el tipo T es equivalente a T’
(T  T’).

Equivalencia Estructural:

T  T’ si y solo si T y T’ tienen la misma estructura.

Mediante la equivalencia estructural se hará el chequeo de tipos


comparando las estructuras de los tipos T y T’. (No es necesario, y
en general imposible, enumerar todos sus valores).

UTN
FRRe
Equivalencia de Tipos. Estructural
 Si T y T’ son dos tipos primitivos.
◼ Luego T  T’ si y solo sí T y T’ son idénticos.
Ej: Integer  Integer.

 Si T = A x B y T’ = A’ x B’.
◼ Luego T  T’ si y solo sí A  A’ y B  B’.
Ej: Integer x Character  Integer x Character

 Si T = A + B y T’ = A’ + B’.
◼ Luego T  T’ si y solo sí A  A’ y B  B’ o A  B’ y B  A’.
Ej: Integer + Character  Character + Integer

 Si T = A → B y T’ = A’ → B’.
◼ Luego T  T’ si y solo sí A  A’ y B  B’.
Ej: Integer → Character  Integer → Character

 En otro caso, T no es equivalente a T’.

UTN
FRRe
Equivalencia de Tipos. De Nombres.
Equivalencia de Nombres

T  T’ si y solo si T y T’ fueron definidos en el mismo lugar.

T  T’ si y solo si T y T’ poseen los mismos nombres.

type T1 = file of Integer;


T2 = file of Integer;
var F1: T1;
F2: T2;
Qué pasará con las
procedure p (var F: T1);
begin
siguientes llamadas al
... procedimiento p?
end;
p(F1) y p(F2)
UTN
FRRe
Equivalencia Estructural vs.
Equivalencia de Nombres
¿Cuál de los dos enfoques es mejor?

 Las razones principales por las que suele preferirse la equivalencia


de nombres son:
◼ La equivalencia de nombres suele ser más segura.
◼ Se presume que si un programador declara dos veces el mismo tipo es
porque tiene una razón para hacerlo.
 Por lo tanto, considerar estos tipos como diferentes protege la
seguridad del programa (previene al programador de hacer algo sin
sentido).
◼ La equivalencia de nombres es más fácil de implementar. El compilador
sólo tiene que comparar las cadenas de caracteres que representan los
nombres de los tipos.
◼ Para implementar la equivalencia estructural, es necesario
escribir una función recursiva que compare las estructuras de
datos que representan los tipos de los dos objetos bajo
consideración. Esto también suele impactar la eficiencia del
compilador (lo hace más lento).

UTN
FRRe
Type Systems

We say that type T is compatible with


type S, if a value of type T is permitted
in any context in which a value of type
S would be admisible.

UTN
FRRe
¿Probamos algo?

¿Qué podríamos
hacer para validar la
técnica que tiene un
lenguaje de
programación para
la equivalencia de
tipos?

UTN
FRRe
Principio de Completitud de Tipos
 “Las operaciones que se puedan realizar con los
valores pertenecientes a un tipo, no deberían ser
arbitrariamente restringidas al mismo”.
Este principio debe contribuir a que los lenguajes no posean restricciones sobre
las operaciones que pueden aplicarse a valores de determinados tipos y de esa
manera reducir la potencialidad de un lenguaje de programación.
Sin embargo, una restricción podría justificarse por otra, conflicto,
consideraciones de diseño, etc.

Ejemplos:
•Se pueden pasar funciones como argumento
map par [1,1,2,3]; map cuadrado [1,1,2,3]
•Se pueden devolver funciones como resultado de otra función
(may 4) 7; map (may 4) [3,3,6,7,8,3]
•Se pueden almacenar funciones dentro de otras estructuras
mapping [cuadrado, doble] 4

UTN
FRRe
UTN
FRRe
73… el mejor número?

UTN https://www.youtube.com/watch?v=R7hTUxzbH48&t=249s
FRRe https://www.youtube.com/watch?v=ShkAMt0Ye2o
Sistemas de Tipos
Cada constante, variable, resultado de
función y parámetro formal, deben
declararse con un tipo específico.

Monomórficos

Polimórficos
Se utilizan estrategias que relajan el
control de tipos.

UTN
FRRe
Sistemas de Tipos Polimórficos
 Polimorfismo de Parámetros: es una propiedad de una
única abstracción que tiene una (amplia) gama de tipos
relacionados; la abstracción opera uniformemente sobre sus
argumentos cualquiera sea su tipo.

 Polimorfismo de inclusión: habilidad de subtipos y subclases


de heredar operaciones de sus tipos padres o superclases.

 Sobrecarga: significa que un número (pequeño) de


abstracciones distintas están asociadas al mismo identificador
en el mismo ámbito; estas abstracciones no necesariamente
deben tener tipos relacionados, ni realizar necesariamente
operaciones similares en sus parámetros.
 Conversión de tipos: es un mapeo entre valores de un tipo a
valores de un tipo diferente.

 Tipos parametrizados: son tipos que toman otros tipos como


parámetro.

UTN
FRRe
Polimorfismo de Parámetros
Las abstracciones operan uniformemente sobre argumentos
de una amplia gama de tipos.
type conjNum = set of 1..10; Tipo de la función:
1..10 x 1..10 → boolean
function disjunto (s1, s2: conjNum) : boolean;
begin
disjunto := (s1 * s2 = []);
end;

var
numeros : conjNum;

begin
numeros := [9,2,5];
if disjunto (numeros, [1,2,3])
then writeln ('Son disjuntos')
else writeln ('No son disjuntos');
end.

UTN
FRRe
Polimorfismo de Parámetros 2
En un sistema de tipos polimórfico, las abstracciones pueden
operar uniformemente sobre argumentos de una amplia
gama de tipos.

Tipo de la función: Tipo de la función:


Int x Int → Int x→

Ejemplo 2:
fun segundo (x: int, y: int) = y fun segundo (x: , y: ) = y

segundo (13, 21) retornará 21. segundo (13, true) es legal.

segundo (13, true) ilegal segundo (13) es ilegal


segundo (13) ilegal segundo (1859, 2, 21) es ilegal
segundo (1859, 2, 21) ilegal

UTN
FRRe
Polimorfismo de Inclusión
En un sistema de tipos donde los tipos pueden tener subtipos
que heredan operaciones del tipo padre. Específicamente
caracteriza a los OOL donde las clases pueden tener
subclases que heredan los métodos de la superclase.

Enteros (Z) N  Z; por lo tanto, un


valor del subtipo N puede
usarse donde se espera
un valor del tipo Z.
Naturales (N)
Z tienen un conjunto de
operaciones asociadas
que son aplicables
también a cualquier valor
de N.

UTN
FRRe
Polimorfismo de Inclusión
En general, si C es una clase, esta incluye, no solo objetos de la
clase C, sino también objetos de cualquier subclase de C.
Cada objeto de la subclase, potencialmente hereda, todas los
métodos de la clase C.

Figura Cualquier puntero a un


objeto de Figura puede
apuntar a un objeto de
cualquiera de sus
subclases.
Cuadrado Círculo Triángulo

UTN
FRRe
¿Probamos algo?

¿Vemos cómo
funciona el
polimorfismo de
inclusión?

polimor.cpp

UTN
FRRe
Sobrecarga
Un identificador u operador se dice que está sobrecargado
si denota simultáneamente dos o más funciones distintas en
el mismo entorno.

Ejemplo 1: el operador ‘-’ denota simultáneamente cinco funciones


distintas.

Negación de un entero (una función de Integer → Integer)


Negación de un real (una función de Real → Real)
Diferencia de enteros (una función de Integer x Integer → Integer)
Diferencia de reales (una función de Real x Real → Real)
Diferencia de conjuntos (una función de Set x Set → Set)

Ejemplo 2: el operador ‘/’ en Ada denota dos funciones distintas:


División de enteros (una función de Integer x Integer → Integer)
División de reales (una función de Real x Real → Real)

UTN
FRRe
Sobrecarga
Definamos una función suma de
complejos
fun suma (c1: complex, c2: complex) -> complex
{
z: complex

z.real = c1.real + c2.real


z.img = c1.img + c2.img
retornar z
}

UTN
FRRe
Sobrecarga
Definamos una función suma de
polinomios

fun suma (p1: poli; p2: poli) -> poli


{ r: poli
for (...)
r[i] = p1[i]+p2[i]
retornar r
}

UTN
FRRe
Sobrecarga… un ejemplo más
fun div (a: int; b: int) : int; 1
{ ... }

fun div (a: int; b: int) : float;


2
{ ... }
----------------------------------
suma (a: float, b: int) : int
----------------------------------
suma (div (7, 2), x);
UTN
FRRe
Sobrecarga
Un ejemplo C++

C1 = -3 + 4i
C2 = 5 – 2i

C1 + C2

UTN
FRRe
Sobrecarga 3
I denota a una función f1: S1 → T1
f2: S2 → T2

 Sobrecarga independiente del contexto (como en Pascal y ML):


requiere que S1 y S2 sean distintos. Considere la llamada a la función I (E).
Si el parámetro actual E es del tipo S1, entonces I denota a f1 y el
resultado es del tipo T1; si E es del tipo S2, entonces I denota f2 y el
resultado será del tipo T2. Con la sobrecarga independiente del contexto la
función que se llama es identificada unívocamente por el parámetro actual.
 Sobrecarga dependiente del contexto (como en Ada): requiere que S1
y S2 sean distintos o que T1 y T2 sean distintos. Si S1 y S2 son distintos, la
función a llamar puede identificarse como anteriormente. Si S1 y S2 no son
distintos, pero T1 y T2 son distintos, el contexto debe tenerse en cuenta
para identificar la función que se llamará. Considere la llamada a la función
I(E), donde E es del tipo S1 ( S2). Si la llamada a la función ocurre en un
contexto donde se espera una expresión del tipo T1, entonces I debe
denotar a f1; si la llamada a la función ocurre en un contexto donde se
espera una expresión del tipo T2, entonces I debe denotar f2. Con la
sobrecarga dependiente del contexto, es posible formular expresiones en
las cuales la función a llamar no pueda ser identificada unívocamente pero
el lenguaje debe prohibir esas expresiones ambiguas.

UTN
FRRe
Conversiones de Tipos
 Una conversión de tipos es un mapeo entre valores de
un tipo a valores de un tipo diferente.

 Ejemplos
◼ Mapeos de valores a otros matemáticamente iguales (enteros a
reales)
◼ Mapeos de valores a otros próximos (mediante truncamiento o
redondeo)
◼ Mapeos 1 a 1 (caracteres a strings de longitud 1)
◼ Mapeos totales (caracteres a ASCII)
◼ Mapeos parciales (ASCII a caracteres)

UTN
FRRe
Conversiones de Tipos. Clasificación

Un cast es una conversión explícita. En C, C++ y Java, un cast


tiene la forma (T)E (produce un mapeo del valor representado por
la expresión E (de tipo S) a su correspondiente valor de tipo T.

Una coerción, es una conversión de tipos implícita y se ejecuta


automáticamente cuando el contexto sintáctico lo requiere.

Ej: sqrt (n) >> la función sqrt espera un argumento del tipo real,
pero n es de tipo entero, se realiza el siguiente mapeo:
{..., -2 → -2.0, -1 → -1.0, 0 → 0.0, 1 → 1.0, 2 → 2.0, ...}

UTN
FRRe
Tipos parametrizados
 Un tipo parametrizado es aquel que toma otro/s tipo/s como
parámetros
◼ Como ejemplo podemos considerar la construcción de tipos arreglo en C o
Pascal: Tipos predefinidos parametrizados
 int []; float[]; array [S] of T

◼ Solo algunos lenguajes permiten al programador construir tipos


parametrizados nuevos:

data MayBe a = Nothing | Just a

data Either a b = Left a | Right b

data Lista a = LVacia | Par (a, Lista a)

data Tree a = Vacio | Rama (Tree a) a (Tree a)

UTN
FRRe
UTN
FRRe
5 minutos para un recreo mental!

Manzanas Naranjas Manzanas+Naranjas

Hay 3 cajas cargadas con frutas, una tiene solo manzanas, otra tiene solo
naranjas y la última tiene manzanas y naranjas revueltas. Las 3 están
etiquetadas con manzanas, naranjas y manzanas+naranjas pero
erróneamente.
¿Puedes abrir solo una, sacar una fruta sin asomarte en el interior y aún así
etiquetar las tres cajas correctamente con tan solo ver esa fruta?

UTN
FRRe
Contenidos 2

Valores y Tipos Variables y Abstracciones


actualización
Tipos Primitivos Tiempo de Vida de una Parámetros
Tipos Compuestos variable Mecanismos de Paso de
Control de Tipos Enlace y Ámbito Parámetros
Equivalencia de Tipos Alcance y Visibilidad Ordenes de Evaluación
Principio de Completitud de Tipos Alcance Estático y Dinámico
Sistemas de Tipos
Sobrecarga, Polimorfismo y
Conversiones de Tipos

UTN
FRRe
Variables y Actualizaciones
 En lenguajes imperativos, OOL y concurrentes, una
variable es el contenedor de un valor, este valor
puede ser inspeccionado y actualizado tanto como se
desee.
◼ Vida Corta: Las variables que se crean y se usan en
un programa particular, tales variables son
típicamente actualizadas por la asignación.
◼ Larga Vida: Archivos y bases de datos.

Un almacén es una colección de celdas.


Cada celda tiene un estado actual: reservado o no reservado.
Cada celda reservada tiene un contenido actual, que es un
valor almacenable o indefinido.

UTN
FRRe
Variables y Actualizaciones

Declaración:
var n: Integer NoReservado
Reservado
n
0
1

Asignación Final del


n := 0 bloque de la
declaración
Asignación
n := n + 1

UTN
FRRe
Tiempo de Vida de una Variable
Variables globales y locales
 El intervalo entre la creación y la eliminación es
llamado tiempo de vida de una variable.
program P;
var x: ...;
procedure Q; eP eQ eR sR sQ eR sR sP
var y: ...;
begin
... R ... Vida de z
end
procedure R;
var z: ...; Vida de y Vida de z
begin
... Vida de x
end;

begin
... Q ... R ...
end.

UTN
FRRe
Tiempo de Vida de una Variable 2
 Variables de pila
◼ Este tipo de variables pueden ser creadas y
borradas en cualquier momento. Se crean y se
destruyen con un comando. Son anónimas y
pueden ser accedidas a través de un puntero.

 Variables Persistentes
◼ Una variable persistente es aquella cuyo tiempo
de vida va más allá del tiempo de ejecución de
un determinado programa

UTN
FRRe
¿Probamos algo?

¿Podremos crear
algunas variables de
pila y validar que su
vida excede la
estructura de
bloques?

fpc var_pila.pas
.\var_pila.exe

UTN
FRRe
Enlace y Ámbito
 Enlace
◼ Es una asociación fija entre un identificador con una
entidad tales como constantes, variables, procedimientos,
funciones y tipos.
◼ La buena elección de identificadores ayuda a hacer que los
programas sean más comprensibles y fáciles de interpretar.
◼ Más aún, relacionar un identificador con una entidad en un
lugar y luego utilizar ese identificador para hacer referencia
a esa entidad en otros lugares, hace que los programas
sean más flexibles.

Podemos decir que una declaración produce


una asociación o un enlace entre el
identificador declarado y la entidad que
denotará.

UTN
FRRe
Enlace y Ámbito 2
 Ámbito
◼ Un entorno o ámbito (o espacio de nombres) es
un conjunto de enlaces.

 Cada expresión o comando se interpreta en un entorno


particular y todos los identificadores usados en una
expresión o comando deben estar enlazados en ese
entorno.
 Es posible que expresiones o comandos en diferentes
partes de un programa sean interpretados en diferentes
entornos.
 Normalmente, al menos un enlace por identificador se
permiten en algún ambiente.

UTN
FRRe
Enlace y Ámbito 3

program p; {
const z = 0; c → una variable de tipo carácter,
var c: char; q → un procedimiento,
z → el entero 0
procedure q;
}
const c = 3.0e6;
var b: boolean;
begin {
b → una variable que contendrá un
2 ... valor de verdad,
end; c → el número real 3000000.0,
begin q → un procedimiento,
1 ... z → un entero 0
end. }

UTN
FRRe
Alcance y Visibilidad
 En general cada declaración tiene un cierto alcance,
que tiene que ver con la porción del programa sobre
el cual al declaración es efectiva.
Declaración de x

Declaración de y Alcance de la declaración de x

Declaración de y

? Alcance de la declaración de y

Qué ocurre si hacemos


una nueva declaración de
Declaración de z
‘y’ en un bloque
Alcance interior?
de la declaración de z

Estructura de bloque anidado

UTN
FRRe
Visibility Rules

A declaration local to a block is visible in


that block and in all blocks listed within
it, unless there is a new declaration of
the same name in that same block. In
this case, in the block which contains
the redefinition the new declaration
hides the previous one.

UTN
FRRe
Scope
Definiciones Previas
 Ocurrencia de Enlace de un Identificador: es el
punto en donde un identificador se declara.
 Ocurrencia de Aplicación de un Identificador:
cuando denota a la entidad a la cual fue enlazado.

Ocurrencia de Enlace
const n = 7

Ocurrencia de Aplicación 1

n * (n+1)
Ocurrencia de Aplicación 2

UTN
FRRe
Scope

const s = 2;
function escalar (d: integer): integer;
begin
escalar := d * s; Cuál es la respuesta
end; que dará la función
escalar en los
procedure ... ;
const s = 3; puntos 1 y 2? ??
begin
2 ... escalar (h) ...
end;

begin
1 ... escalar (h) ...
end.

UTN fpc prueba_Scope.pas


FRRe .\prueba_Scope.exe
Scope
Tipos

based on the text of based on the flow of


the program execution

UTN
FRRe
Scope
Tipos
 El scope estático y dinámico tiene que ver con el momento en
que determinamos que ocurrencia de enlace del
identificador I se corresponde con la ocurrencia de
aplicación de I.

 Con el alcance estático podemos determinar que ocurrencia


de enlace de I se corresponde con una ocurrencia de
aplicación de I dada, solo con examinar el código del
programa, encontrando el bloque más pequeño que
contiene una ocurrencia de aplicación de I que también
contiene una ocurrencia de enlace de I. La asociación entre
la ocurrencia de aplicación y enlace es fija.
 Con enlace dinámico la ocurrencia de enlace de I que se
corresponde con una ocurrencia de aplicación de I depende
del flujo de control dinámico del programa. La entidad
denotada por I es la declaración elaborada más
recientemente de I dentro del bloque activo actual.

UTN
FRRe
Ejemplo
{const x = 0;
void fie(){ Cuál es la respuesta
write(x); 1 que dará la función
} write en el punto 1?
void foo(){
const x = 1;
{const x = 2;
}
fie();
}
foo();
}

UTN
FRRe
Alcance y Lenguajes de Programación
 La mayoría de los lenguajes de
programación, tales como C, java,
Ada tienen alcance estático.

 Unos pocos lenguajes (Smalltalk y


primeras versiones de Lisp) tienen
alcance dinámico, aunque
últimamente algunos lenguajes
siguen implementando este concepto.
UTN
FRRe
Scope
Estático y Dinámico

const ss == 2;
const 2;
0.5;
function escalar (d: integer): integer; Qué pasará si
begin cambiamos la
escalar := d * s; constante global s
end; por 0.5?

procedure ... ;
const s = 3;
begin
2 ... escalar (h) ...
end;

begin
1 ... escalar (h) ...
end.

UTN
FRRe
Contenidos 3

Valores y Tipos Variables y Abstracciones


actualización
Tipos Primitivos Tiempo de Vida de una variable Parámetros
Tipos Compuestos Enlace y Ámbito Mecanismos de Paso de
Control de Tipos Alcance y Visibilidad Parámetros
Equivalencia de Tipos Alcance Estático y Dinámico Ordenes de Evaluación
Principio de Completitud de Tipos
Sistemas de Tipos
Sobrecarga, Polimorfismo y
Conversiones de Tipos

UTN
FRRe
Abstracciones
Instrucciones para subir una escalera
Nadie habrá dejado de observar que con frecuencia el suelo se pliega de manera tal que una parte
sube en ángulo recto con el plano del suelo, y luego la parte siguiente se coloca paralela a este plano, para dar
paso a una nueva perpendicular, conducta que se repite en espiral o en línea quebrada hasta alturas
sumamente variables. Agachándose y poniendo la mano izquierda en una de las partes verticales, y la derecha
en la horizontal correspondiente, se está en posesión momentánea de un peldaño o escalón. Cada uno de estos
peldaños, formados como se ve por dos elementos, se situó un tanto más arriba y adelante que el anterior,
principio que da sentido a la escalera, ya que cualquiera otra combinación producirá formas quizá más bellas o
pintorescas, pero incapaces de trasladar de una planta baja a un primer piso.
Las escaleras se suben de frente, pues hacia atrás o de costado resultan particularmente
incómodas. La actitud natural consiste en mantenerse de pie, los brazos colgando sin esfuerzo, la cabeza
erguida aunque no tanto que los ojos dejen de ver los peldaños inmediatamente superiores al que se pisa, y
respirando lenta y regularmente. Para subir una escalera se comienza por levantar esa parte del cuerpo situada
a la derecha abajo, envuelta casi siempre en cuero o gamuza, y que salvo excepciones cabe exactamente en el
escalón. Puesta en el primer peldaño dicha parte, que para abreviar llamaremos pie, se recoge la parte
equivalente de la izquierda (también llamada pie, pero que no ha de confundirse con el pie antes citado), y
llevándola a la altura del pie, se le hace seguir hasta colocarla en el segundo peldaño, con lo cual en éste
descansará el pie, y en el primero descansará el pie. (Los primeros peldaños son siempre los más difíciles, hasta
adquirir la coordinación necesaria. La coincidencia de nombre entre el pie y el pie hace difícil la explicación.
Cuídese especialmente de no levantar al mismo tiempo el pie y el pie).
Llegando en esta forma al segundo peldaño, basta repetir alternadamente los movimientos hasta
encontrarse con el final de la escalera. Se sale de ella fácilmente, con un ligero golpe de talón que la fija en su
sitio, del que no se moverá hasta el momento del descenso.

UTN
FRRe
Abstracciones
 Abstracción es un modo de pensamiento en el cual
nos concentramos en las ideas generales más que en
las manifestaciones específicas de estas ideas.

 Nos concentramos sólo en qué hace un


procedimiento; sólo cuando escribimos un
procedimiento nos interesará el cómo implementarlo.

Definiremos una abstracción como una entidad que


engloba una computación.

UTN
FRRe
Abstractions

Control Abstraction Data Abstraction

Provides the Allow the definition and


programmer the ability use of sophisticated
to hide procedural data types without
data referring to how such
types will be
implemented
UTN
FRRe
Abstracciones de Control. Tipos

◼ de Función
function I (fp1; ... ; fpn) : T;
(C)uerpo

◼ de Procedimiento
procedure I (fp1; ... ; fpn);
(C)uerpo

UTN
FRRe
Parámetros
Aumentan la potencia del concepto de Abstracción.

Ej: fun circunf (r: real) = 2 * pi * r


 Parámetro formal: Es un identificador que se usa en
una abstracción, a través del cual se puede acceder a
un argumento.
 Parámetro actual: Una expresión o frase que se
devuelve un argumento.
◼ Ej: circunf (1.0) circunf (a+b)
 Argumento: es el valor u otra entidad que se pasa a
una abstracción.

UTN
FRRe
Paso de Parámetros
 Mecanismo de copia

◼ Un mecanismo de copia permite que valores se


copien a y/o desde una abstracción cuando se
la llama.
◼ El parámetro formal (PF) denota una variable
local para la abstracción.
◼ Un valor se copia en PF a la entrada de la
abstracción, y/o se copia de PF (a una variable
no local) a la salida de la abstracción.
◼ Debido a que PF es una variable local, se crea a
la entrada de la abstracción y se elimina a la
salida.

UTN
FRRe
Paso de Parámetros
Mecanismo de copia 1
 Un parámetro por valor es una variable local X que se
crea a la entrada de la abstracción y se le asigna el valor
del argumento. Debido a que X se comporta como una
variable local, su valor puede ser inspeccionado y
actualizado. Sin embargo cualquier actualización de X no
tiene efecto en ninguna variable fuera del procedimiento.

 Un parámetro resultado es todo lo contrario del anterior.


En este caso, el argumento debe ser una referencia a una
variable. De nuevo una variable local X se crea, pero su
valor inicial es indefinido. A la salida de la abstracción el
valor final de X es asignado a la variable argumento.

 Parámetros valor-resultado. El argumento, de nuevo,


debe ser una referencia a variable. En la entrada de la
abstracción, la variable local X se crea y se le asigna el
valor actual de la variable argumento. A la salida, el valor
final de X se asigna nuevamente a la variable argumento.
UTN
FRRe
Paso de Parámetros
Mecanismo de copia 2
type vector = array [1..n] of real;

procedure sumar (value v, w: vector; result sum: vector);


1 var i: 1..n;
begin
For i := 1 to n do sum[i] := v[i] + w[i];
2 end;

procedure normalizar (value result u: vector);


3 var i : 1..n; s: real;
begin
s:= 0.0;
for i := 1 to n do s := s + sqr (u[i])
s := sqrt(s)
for i := 1 to n do u[i] := u[i]/s
4 end;

UTN
FRRe
Paso de Parámetros
Mecanismo de copia 3

Mecanismo Efecto de Efecto de


Argumento
entrada salida
Parámetro valor
Valor X:= argumento -

Parámetro
Una variable - argumento := X
resultado
Parámetro valor-
Una variable X:= argumento argumento := X
resultado

donde X un parámetro formal.

UTN
FRRe
Paso de Parámetros
Mecanismo por Referencia
 Este mecanismo permite que un parámetro formal, sea enlazado
directamente al argumento.

 Proporciona una semántica uniforme para el paso de parámetros


de cualquier tipo de valores (de 1era clase o no).

◼ En el caso de un parámetro constante, el argumento debe ser


un valor. El parámetro formal FP se enlaza al valor del argumento
durante la activación del procedimiento.
◼ En el caso de un parámetro variable, el argumento debe ser una
referencia a una variable. El parámetro se enlaza a la variable
argumento durante la activación del procedimiento. Por lo tanto
cualquier actualización o inspección del parámetro formal FP es
realmente una actualización o inspección indirecta de la variable
argumento.
◼ En el caso de un parámetro procedural, el argumento debe ser
un procedimiento. El parámetro formal FP se enlaza al
procedimiento durante la activación del procedimiento llamado.
Por lo tanto cualquier llamada a FP es una llamada indirecta al
procedimiento que se pasa como argumento.

UTN
FRRe
Paso de Parámetros
Mecanismo por Referencia 2
type vector = array [1..n] of real;

procedure sumar (const v, w: vector; var sum: vector);


1 var i: 1..n;
Begin
For i := 1 to n do sum[i] := v[i] + w[i];
2 End;

procedure normalizar (var u: vector);


3 var i : 1..n; s: real;
Begin
s:= 0.0;
for i := 1 to n do s := s + sqr (u[i])
s := sqrt(s)
for i := 1 to n do u[i] := u[i]/s
4 end;

UTN
FRRe
Paso de Parámetros
Mecanismo por Referencia 3

Mecanismo Efecto en la
Efecto de
Argumento llamada al
salida
procedimiento
Parámetro Enlaza PF al
Constante Valor argumento -
valor
Parámetro Enlaza PF al
Variable Variable argumento -
variable
Parámetro Enlaza PF al
Procedimiento -
Procedural procedimiento

UTN
FRRe
Paso de Parámetros

Mecanismo por Referencia Mecanismo por Copia

UTN
FRRe
Paso de Parámetros
Mecanismo por Referencia 2: Alias
 Una desventaja de los parámetros variable es la
posibilidad de crear alias.
 Esto ocurre cuando dos o más identificadores son
simultáneamente enlazados a la misma variable.

procedure confuso (var m, n : integer);


begin
n:= 1;
n:= m + n
end;
i := 4
confuso (i, i)
i?
fpc confuso.pas
UTN
.\confuso.exe
FRRe
Call By Name

Let f be a function with a single formal


parameter, x, and let a be an expression of
a type that is compatible with that of x. A
call to f with an actual parameter a is
semantically equivalent to the execution of
the body of f in which all occurrences of
the formal parameter, x, have been
replaced by a.

UTN
FRRe
Parámetros
Orden de Evaluación

El orden de evaluación se refiere


exactamente al momento en que cada
parámetro actual se evalúa cuando se
llama a una abstracción.

UTN
FRRe
Parámetros
Orden de Evaluación

Impaciente Perezoso

UTN
FRRe
Parámetros
Orden de Evaluación 2

Ej. 1:
fun sqr (n: int) = n * n

Si p = 2 y q = 5.

sqr (p + q)

Evaluación Impaciente (Eager): Primero evaluar p+q que


retornaría 7, y luego enlazar el parámetro formal n a 7. Finalmente
evaluar n*n lo cual retornaría 7 x 7 = 49.

Evaluación perezosa (Lazy): Primero enlazar el parámetro formal n


a la expresión p+q en sí, luego cada vez que el valor de n es
requerido durante la evaluación de n*n, reevaluaremos la
expresión a la cual n fue enlazada. Por lo tanto haríamos el
siguiente cálculo (2+5)x(2+5) = 49… (podríamos evitar calcular
dos veces 2+5?).

UTN
FRRe
Parámetros
Orden de Evaluación 4

Evaluación perezosa
(lazy evaluation)

El argumento se evalúa solo cuando se la necesita por primera vez


(que podría ser nunca)

Ejemplos

enumFrom n
take m (enumFrom n)
sum (take m (enumFrom n))

UTN
FRRe
Parámetros
Funciones Estrictas y No Estrictas
Ej. 2:
fun cand (b1, b2 : bool) =
if b1 then b2 else false

Qué devuelve cand (n>0, t/n>0.5) ?

Función
Con n = 2 yEstricta:
t = 0.8
EvaluaciónaImpaciente?
Una llamada función puede Falso solo si sus
evaluarse
Evaluación en Orden Normal?
argumentos pueden ser evaluados. Falso
Función No Estricta:
Con n = 0 y t = 0.8:
Una llamada
EvaluaciónaImpaciente?
esta función puede Falla
a veces
por evaluarse
División por 0
aún cuando algún
Evaluación argumento
en Orden Normal?no pueda
Falsoser evaluado.

UTN
FRRe

También podría gustarte