26
Sistema de tipos Fundamentos de Computación II

Sistema de tipos

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Sistema de tipos

Sistema de tipos

Fundamentos de Computación II

Page 2: Sistema de tipos

SISTEMA DE TIPOS

Un tipo describe un conjunto de valores. Ej: Números: 1, 2, PI, etc. Operaciones: +,-,*. etc.

Un sistema de tipos define cómo un lenguaje de programación clasifica los valores y las

expresiones en tipos que tienen sentido para ser utilizados en una operación dada.

Al asignarle un tipo a una expresión se está delimitando cuál es el conjunto de valores

que podría tener esa expresión. Las operaciones computacionales en general no pueden

ser aplicadas sobre cualquier valor.

Ejemplo:

• x e y : valores numéricos

• x e y :valores booleanos La expresión x + y ¿tiene sentido?

La idea de tipo permite relacionar:

✓un conjunto de valores que tienen ese tipo o son de ese tipo,

✓con las operaciones que pueden ser realizadas sobre esos valores.

La expresión x + y ¿tiene sentido?

Page 3: Sistema de tipos

¿Y EN OBJETOS?

En objetos se trabaja objetos y mensajes.

Los son los objetos y las los mensajes.

Conceptos

Tipado: Es la definición del tipo que tendrá una variable dada. Ejemplo si en una variable

queremos guardar numeros enteros, lo mejor es tener una variable de tipo int.

Lenguaje tipado: es el que no permite violación de los datos.

Lenguaje no tipado: Al definir una variable no es necesario definir el tipo.

Puede cambiar en cualquier momento. Ejemplo: pseudocódigo , PHP. En éste lenguaje no

hay ningún problema en que una variable sea una Array y luego se convierta en un entero

o un String. Lisp es un lenguaje sin tipificación.

Page 4: Sistema de tipos

para (i <- 1; i<=100; i++)

{ establecer numero a verdadero;

si i es divisible por 3 escribir “HOLA";

establecer numero a falso;

si i es divisible por 5 escribir “hola";

establecer numero a falso;

si numero, escribir i; escribir una nueva línea; }

Hay una variable declarada i asociada a un contador pero no se sabe de que tipo es la variable. Si revisamos el código nos damos cuenta que i al ser inicializada recibe el numero 1, pero no nos preocupamos por que tipo de valor recibe la variable, solo sabemos que proceso se quiere hacer, pero si deseamos pasar el pseudocódigo a programación real, en el caso de C que es fuertemente tipado, debemos decirle que la variable es un entero.

Page 5: Sistema de tipos

Tipado débil

No se indica el tipo de variable al declararla. Se puede asignar, por ejemplo, un valor entero a

una variable que anteriormente tenía una cadena. También se puede operar aritméticamente

con variables de distintos tipos: ej: sumar “x” + 5. Lenguajes que lo usan: PHP, java script

Ventajas Desventajas

Nos olvidamos de declarar el tipo Al hacer operaciones, a veces éstas salen mal. Se pueden cometer muchos errores.

Podemos cambiar el tipo de la variable sobre la marcha. Por ejemplo, asignarle un string a un int

“20” > “100” dará como resultado true, ya que son comparados como cadena, no como números.

Escribimos menos código Hay que castear

Es más rápido de desarollar Al declarar los argumentos de una función no sabemos si ésta espera un flotante, un entero, un string, etc. Tenemos que ir a la función, ver lo que hace e inferir el tipo de variable que espera.

Page 6: Sistema de tipos

Quien infiere los tipos es el propio lenguaje

Ejemplo en JavaScript

Una diferencia con el tipado fuerte es que el tipado débil se puede asignar, por

ejemplo, un valor entero a una variable que anteriormente tenía una cadena.

Page 7: Sistema de tipos

Tipado fuerte

Se le indica el tipo de dato al declarar la variable. Dicho tipo no puede ser cambiado

nunca. Y no se puede operar entre distintos tipos. Lenguajes: Ruby, Python,…

Ventajas Desventajas

Código expresivo: por ejemplo en una función se sabe de qué tipo espera un argumento una función

Escribir más código: hay que declarar el tipo de variable.

Menos errores: Nos olvidamos de ver el tipo de variable antes de hacer operaciones con ésta

Ejemplo: si realizamos la operación de “x” + 5 en Python:

Page 8: Sistema de tipos

Los de tipado fuerte son mucho más seguros, porque no permiten hacer operaciones con

variable de distintos tipos y eso permite que no se comentan tantos errores, lo que puede

ser conveniente para proyectos de gran envergadura.

Los de tipado débil se puede trabajar mucho más rápido, lo que permite obtener resultados

antes, lo que es bueno cuando se está en fase de ideación o de proyectos más pequeños.

Según de qué proyecto se trate se usa un tipado u otro.

¿Cuál es mejor?

Page 9: Sistema de tipos

Tipado Dinámico: el tipo de dato se comprueba en tiempo de ejecución. No es

necesario definir los tipos al declarar una variable. Ejemplo: PHP, JavaScript,

Grooby, Python, Perl.

Tipado Estático: el tipo de dato lo define el programador, se comprueba una vez

que se compila el programa. El tipado estático nos obliga a definir desde el

principio el tipo de una variable, Ejemplo: C, C++, Pascal, Java.

Page 10: Sistema de tipos

✓Ayudar a detectar errores al programar.

✓Guiar al programador sobre las operaciones válidas en un determinado contexto, tanto

en cuanto a documentación como en cuanto a ayudas automáticas que puede proveer

por ejemplo un IDE.

✓En algunos casos el comportamiento de una operación puede variar en función del

tipo de los elementos involucrados en la misma. De esto vamos a diferenciar varios

sabores: polimorfismo, sobrecarga, multimétodos, etc.

Algunas características de un sistema de tipos:

✓Proveen información al programador, de forma más precisa que un comentario.

✓Un sistema de tipos debería permitir hacer validaciones utilizando la información de

tipos, algorítmicamente.

✓Las validaciones basadas en un sistema de tipos, son más fácilmente automatizables

que otros tipos de especificaciones formales.

¿Para qué sirve el sistema de tipos?

Page 11: Sistema de tipos

Conversiones

Conversión implícita: cuando el valor que se va a almacenar puede ajustarse a la variable sin

necesidad de truncamiento o redondeo.

Ejemplo: una variable de tipo long entero de 8 bytes puede almacenar cualquier valor que

pueda almacenar a su vez un elemento int : 4 bytes en un equipo de 32 bits.

int num = 21474833647;

long Num = num;

El compilador convierte implícitamente el valor de la derecha en un tipo long antes de asignarlo a Num.

Page 12: Sistema de tipos

Conversión explicita o conversión de tipo:

Una conversión de tipo es una manera de informar al compilador de forma explicita de que

pretende realizar la conversión y que esta al tanto de que puede producirse una perdida de

datos. Para realizar una conversión de tipo, se debe especificar entre paréntesis el tipo al

que se va a aplicar dicha conversión delante del valor o la variable que se va a convertir.

int main(){

double x;int a=3;// Cast int a double.x = a/2 ;cout << x;

}

La salida es: 1

int main(){

double x;int a=3;// Cast int a double.x = (double) a/2 ;cout << x;

}

La salida es: 1,5

Page 13: Sistema de tipos

Razones para verificar tipos estática (en tiempo de compilación)

1. Eficiencia de ejecución: la información de tipos estáticos permite a los compiladores

asignar memoria con eficiencia y generara código de máquina que manipula los datos

eficientemente.

2.- Eficiencia de traducción: un compilador puede utilizar los tipos estáticos a fin de

reducir la cantidad de código que necesita compilar.

3.- Capacidad de escritura: muchos errores estándar de programación son detectados

rápidamente.

4.- Mejora la seguridad, la confiabilidad y la legibilidad.

5.- Mejora el desarrollo de los programas grandes al verificar la consistencia y corrección

de la interfaz.

Page 14: Sistema de tipos

Se pueden producir dos tipos de errores durante la ejecución de un programa:

✓ Trapped (atrapados)

Son los errores que se detectan inmediatamente, por ejemplo una división por cero.

✓Untrapped (no atrapados)

Son errores que pueden no ser detectados. El programa podría continuar ejecutándose

por un tiempo antes de detectar el problema.

Por ejemplo si se accede a posiciones de un array más allá de su longitud o se salta a una

posición inválida de memoria.

Todos los errores de tipo se detectan en tiempo de compilación.

Detección de errores

Page 15: Sistema de tipos

Momento del checkeo

Se refiere a la capacidad del lenguaje de verificar que una operación es válida para un

objeto dado.

1. Chequeo estático

Se realiza antes de la ejecución (por ejemplo, los realiza el compilador).

Ejemplos "puros": Haskell y Scala hacen todos sus chequeos en forma estática.

Ejemplos "impuros": Java y C hacen chequeos en forma estática, pero esto no es

todo lo que pasa.

2. Chequeo dinámico

Se realiza durante la ejecución.

Al encontrarse un error de tipos durante la ejecución / evaluación, el lenguaje lo

detecta y modela.

Un ejemplo que conocemos todos es Smalltalk. El modelo de error de tipo es el

DoesNotUnderstand. Otros ejemplos: Python, Ruby.

Page 16: Sistema de tipos

3. No chequea en ningún momento

Al encontrarse un error de tipos durante la ejecución / evaluación, el lenguaje no

lo detecta, y las consecuencias son impredecibles.

Page 17: Sistema de tipos

Tipos nominales y estructurales

Tipado nominal

En un sistema de tipos nominal, dos tipos son compatibles si tienen el mismo

nombre, independientemente de que tengan los mismos elementos o no.

En un sistema de tipos nominal, se puede tener dos tipos con «idénticos» valores

posibles, pero que no son compatibles entre sí.

class Person {

public int Id { get; set; }

public string Name { get; set; }

}

class Product {

public int Id { get; set; }

public string Name { get; set; }

}

Person paco = new Person { Id = 2, Name = "Paco" };

Product morcilla = paco; // error!

Person y Product son estructuralmente idénticos y pueden tomar

exactamente los mismos valores, concretamente, todos los posibles

pares de int y string. Sin embargo, para el sistema de tipos de C#, los

elementos de un conjunto no son compatibles con los del otro

Page 18: Sistema de tipos

1234

typedef char CHARACTER;

char c1 = 'a';CHARACTER c2 = c2; // OK, es sólo un alias, no un nuevo tipo

Hay lenguajes que permiten definir alias sobre tipos, de forma que podamos referirnos a

un tipo con varios nombres, pero sin considerarlos tipos diferentes.

Por ejemplo, en C podemos usar typedef.

Page 19: Sistema de tipos

Tipado estructural:

Se basa en la estructura de los tipos.

En un sistema de tipos estructural dos tipos son compatibles si la estructura de sus

elementos es compatible, es decir que el tipo desde el que estamos asignando contiene, al

menos, la misma información que el tipo al que estamos asignando.

Smalltalk o Ruby, el tipado es naturalmente estructural. Por ejemplo:

#Titiretero

darFuncion: titeretitere decir: 'Hola!'titere levantarBrazotitere decir: 'Adios!'

No especifica de qué tipo es "titere", ya que no se declaran los tipos de las variables

Dentro del cuerpo del método le envía dos mensajes: decir y levantarBrazo. Estas son las características que se espera

del títere en este método.Implícitamente se está definiendo que el objeto títere tiene que cumplir con el tipo que define estos dos mensajes. Este tipo no tiene nombre, la especificación del tipo requerido

no es nominal.A eso se le llama DuckTyping!

Page 20: Sistema de tipos

TABLAS COMPARATIVAS

Momento del chequeo Mayormente estático, pero en presencia de chequeos se hace dinámico. Modelo de error de tipos en chequeo dinámico: ClassCastException.

Información de tipos que hay que escribir Mucha, está muy del lado explícito.En la "cultura Java" se considera esto una ventaja, se dice que facilita la comprensión de las interfaces y de los programas, para las personas que los tienen que usar y mantener.

Identificación de tipos Nominal.

Lenguajes similares C# (hasta donde sabemos)

JAVA

Page 21: Sistema de tipos

Momento del chequeo Dinámico, modelo de error de tipos: DoesNotUnderstand.

Información de tipos que hay que escribir

La mínima posible, está muy del lado implícito.La idea es minimizar la cantidad de "burocracia" en el código. El nombre del lenguaje es muy claro al respecto.

Identificación de tipos Naturalmente estructural : no se le pone nombre a los tipos.

Lenguajes similares Ruby (hasta donde sabemos)

SMALLTALK

Page 22: Sistema de tipos

Momento del chequeo Estático. Muy preocupado desde la concepción por evitar errores de tipos. Da herramientas para permitir polimorfismo.

Información de tipos que hay que escribir

Muy poca, está muy del lado implícito. Entre sus objetivos está aprovechar la inferencia de tipos todo lo que se pueda. En algunos (pocos) casos a la inferencia no le da la nafta, y el programador debe ayudarla poniendo algo de información de tipos.

Identificación de tipos En general nominal, hay mecanismos de tipado estructural provistos por el lenguaje (polimorfismo paramétrico).

Lenguajes similares no conocemos

HASKELL

Page 23: Sistema de tipos

Se plantearon tres clasificaciones:

✓En cuanto a la forma de chequeo: puede ser estático/compile time, dinámico/runtime o

nada.

✓En cuanto a la forma de especificar el tipo de algo : puede ser explícito o implícito /

✓En cuanto a la forma de constituir un tipo: puede ser nominal o estructural.

Resumen

Page 24: Sistema de tipos

¿Como seria un lenguaje de programación ideal?

✓Que tenga chequeo estático, para no tener que preocuparse por los errores de tipos,

que los verifique el lenguaje.

✓Que el tipado sea implícito, para escribir menos código.

✓Que la identificación de tipos sea estructural, para que permita aprovechar más el

polimorfismo, lo que implica que tengo que preocuparme menos por cuándo voy a

poder usar un objeto en un determinado contexto: si puedo el lenguaje me va a dejar

sin que tenga que hacer nada, si no puedo me va a dar error de tipos en forma estática

porque ya pedio chequeo estático.

Buscando el lenguaje perfecto

Page 25: Sistema de tipos

Un programador con una visión más "organizativa” podría preferir tipado explícito, e

incluso identificación nominal.

La razón es que aunque el programa queda más largo, y tal vez más difícil de armar, al

poner mucha información de tipos y ponerle un nombre a cada tipo que se está

manejando, hay mucha documentación que queda dentro mismo del programa.

Esta visión tiene adeptos particularmente en proyectos grandes, por los que pasan muchos

programadores.

A un programador con mucha autoconfianza podría preocuparle poco que el chequeo sea

estático, si igual sabe bien lo que está haciendo.

¿Y las conclusiones? Las decide cada uno.

Page 26: Sistema de tipos

EJERCICIO

1. Investigue como seria, en los lenguajes BASIC, COBOL, PASCAL, UNIX Y DBASE:

▪La declaración de las variables A,B y C de tipo entero.

2. Si A=2, B=3 y C=5

Investigar, en los mismos lenguajes, las operaciones:

▪A+B,

▪C-B,

▪B/A,

▪A*C y

▪A**B.