Conversão de Tipos
description
Transcript of Conversão de Tipos
Conversão de Tipos
• Exemplo: x + i, onde x é do tipo real e i é do tipo integer.
• A especificação da linguagem deve indicar se a linguagem suporta este tipo de expressão, e qual a conversão necessária.
• Conversões neste caso podem ser inseridas pelo typechecker: (+.real) x (inttoreal (i))
Coerções
• Conversões de tipo implícitas são chamadas de coerções.
• Coerções normalmente são limitadas a conversões em que não há perda de informação: inteiro para real, mas não o contrário.
• Conversões explícitas são idênticas às aplicações de funções normais.
Coerções (cont.)
• Exemplos de tratamento de conversões em diferentes linguagens:– Ada: sempre explícitas– Pascal e Haskell não misturam caracteres e
inteiros, como ocorre em C.– x é um array de float, há alguma diferença em
inicializá-lo nas formas abaixo?for (i=0;i<n;i++) {x[i] = 1;}for (i=0;i<n;i++) {x[i] = 1.0;}
Overloading de funções e operadores
• Um símbolo é overloaded se o seu significado depende do contexto. Exemplos: – operador ‘+’ em floats, inteiros, números
complexos etc.– ‘(‘ e ‘)’ em Ada: índice de arrays, chamada de
funções, conversão de tipos (cast).• overloading é resolvido quando um valor
único para o símbolo é determinado.
Descobrindo os tipos de operadores overloaded
• Ao invés de trabalharmos com o tipo de uma expressão, podemos trabalhar com o conjunto de tipos possíveis de uma expressão.
• Na maioria das linguagens uma expressão tem que ter (ao final da verificação) um único tipo!
Descobrindo os tipos de operadores overloaded (cont.)
E E1 { E.types = E1 .types }
E id { E.types = lookup(id.entry) }E E1 (E2) { E.types =
{ t | s E2 .types st E1.types}}
Funções e operadores polimórficos
• procedimento ou função que pode ser executado com argumentos de tipos diferentes.
• Exemplos built-in nas linguagens: índices de arrays, aplicação de funções, operações sobre ponteiros.
Por que funções polimórficas?
• Facilitam a implementação de algorítimos que manipulam estruturas de dados, independentemente do tipo da estrutura.
• Exemplo: Pascal (ou C) vs. Haskell
Exemplo em Pascal• type link = ^cell;
cell = record info: integer; next: link; end;function length (lptr : link) : integer;var len : integer;begin len = 0; while (lptr <> nil) do begin len := len + 1; lptr := lptr^.next; end; length := len;end;
Exemplo em Haskell
• length :: [t] -> Int;length [] = 0length (a:as) = 1 + length as
ou• length :: [t] -> Int;
length lptr = if null lptr then 0 else 1 + length (tail lptr)
Variáveis de tipos
• servem para identificar um tipo que não é conhecido em uma determinada parte do programa.
• Inferência de tipos permite determinar o tipo a partir de seu uso, e.g. descobrir o tipo de uma função a partir de sua definição.
Exemplo: map em pascal (ou C)
• type link = ^cell;function map (lptr : link; procedure p);begin while (lptr <> nil) do begin p(lptr); lptr := lptr^.next; end;end;
Exemplo: deref em pascal (ou C)
• function deref (p);begin return p^;end;
Estendendo a linguagem para suportar polimorfismo
P D ; E D D ; D | id : QQ type_variable . Q | TT T ‘->’ T | T T | unary_constructor ( T ) | basic_type | type_variable | ( T )
Regras para inferência de tipos
• Ocorrências distintas de uma função polimórfica em uma expressão podem ter tipos diferentes.
• Como variáveis podem aparecer em expressões de tipos, temos que rever a noção de equivalência de tipos. Usamos unificação ao invés de equivalência.
• Usar um mecanismo para guardar os resultados da unificação dos tipos.
Substituições, instâncias e unificação
• substituições: mapeamento de variáveis de tipos em expressões de tipos.
• instâncias: tipos mais específicos são instâncias de tipos mais genéricos.
• expressões de tipo t1 e t2 unificam se existe uma substituição S tal que S(t1) = S(t2). Queremos o unificador mais geral, i.e. que gere o mínimo de restrições nas variáveis nas expressões.