Вы находитесь на странице: 1из 567

Escola Politcnica - DEL - EEL670

Linguagens de Programao
Leonardo de Oliveira Nunes 2012/1

Contato: E-mail: lonnes@lps.ufrj.br Sala: I-146 (LPS II) Pgina: https:/ /www.del.ufrj.br/Members/ leonardo.nunes/linguagens-deprogramacao-2012-2

Viso Geral do Curso


Parte I - Fundamentos Evoluo das linguagens, paradigmas, interpretao x compilao, gramticas e anlise sinttica Parte II - Elementos de Linguagens de Programao Escopo de variveis, estruturas de controle, tipos de dados, orientao a objetos Parte III - Scripts Parte III - Programao Funcional Laboratrio: C++

Cronograma
Outubro 15: Introduo, evoluo das linguagens, tipos de linguagens 19: Compilao 22: Sintaxe e Derivao 26: Derivao 29: Nomes e tempo de vida de objetos Novembro 02: Finados 05: Escopo 09: Sobrecarga e Polimorfismo 12: Prova 1 16: Recesso 19: Provvel recesso 23: Trmino Cap. 3 e Fluxo estruturado e no-estruturado 26: Iterao, Recurso, e determinao 30: Tipo de dados, sistemas de tipos e verificao de tipo Dezembro 03: Estruturas e unies, Arrays, Strings 07: Ponteiros e tipos recursivos 10: Coletagem de lixo e listas

Cronograma
14: Subrotinas e abstraes de controle, reviso stack, sequncia de uma chamada 17: Passagem de parmetro 21: P2 24:Recesso 28: Recesso Janeiro 04: Recesso 07: Subrotinas genricas e mdulos 11: Abstrao de dados e orientao a objetos: programao OO 14: Encapsulamento e hereditariedade 18:Inicializao e finalizao, unio dinmica de mtodos,herana mltipla 21: OO 25:OO 28:P3 Fevereiro 01:Scripts: Python 04:Scripts: Python 08:Scripts: Scheme 11: Carnaval 15: Scripts: Scheme 18: Scripts: Scheme 22: P4 25:

Bibliograa

1. Michael L. Scott, Programming Language Pragmatics, Morgan Kraufmann, 3a edio 2.Allen B. Tucker e Robert E. Noonan, Linguagens de Programao, McGraw Hill, 2a edio

Avaliao

4 Provas Listas (opcionais) Laboratrio

Por qu?

Conceitos de linguagens de programao Aprendizado de novas linguagens Funcionamento das linguagens

Entender caractersticas obscuras das linguagens Saber escolher entre diferentes formas de se expressar Fazer bom uso de debuggers, assemblers, ... Simular caractersticas de uma linguagem em outra Fazer uso de novas linguagens

PARTE I Fundamentos

Introduo
Linguagem: Projeto x Implementao O que ser visto: Histrico do projeto de linguagens Introduo implementao

Evoluo das Linguagens 1940-1950


Cdigo de mquina Cdigos hexadecimais Instrues diretas para CPU Especco para arquitetura/CPU Assembler Mnemnicos no lugar de nmeros Macros: reutilizao de cdigo

Linguagem de Mquina: MDC para x86 [1]


55 89 E5 53 00 00 39 C3 75 F6 89 1C 89 EC 04 83 74 10 8D B6 24 E8 6E 00 E4 F0 E8 31 00 00 00 00 00 00 8B 5D 00 00 00 89 37 C3 7E 13 FC C9 C3 29 C3 E8 2A 00 29 C3 39 C3 D8 EB EB 90

Assembler: MDC para x86 [1]


pushl %ebp movl subl andl call movl call cmpl je A: cmpl %esp, %ebp $4, $esp $-16, %esp getint %eax, %ebx getint %eax, %ebx C %eax, %ebx pushl %ebx jle subl B: cmpl jne C: movl call movl leave ret D: subl jmp %ebx, %eax B D %eax, %ebx %eax, %ebx A %ebx, (%esp) putint -4(%ebp), %ebx

Prximo passo...
De linguagens dependentes da arquitetura... ... para linguagens independente da arquitetura 1957: Fortran (e outras ling. logo em seguida) Traduo do cdigo para assembler: COMPILADOR Evoluo do compilador: equivalncia de desempenho

Projeto de Linguagens
Hoje em dia: milhares de linguagens Possveis razes:
Evoluo: diferentes paradigmas Propsito: linguagens especcas para um problema Preferncia pessoal Poder de expresso Facilidade de aprendizado Facilidade de implementao Padronizao Cdigo aberto Bons compiladores Econmicos, patronagem

Evoluo das Linguagens


Ponto de vista do implementador: fcil de criar um compilador Ponto de vista do programador: fcil de descrever algoritmos Knuth: programar a arte de informar outro ser humano o que o computador deve fazer Compromisso: claridade x ecincia

Classicao - Viso Geral


Funcional Declarativas Dataow Lgica Template von Neumann Imperativas Scripting OO Lisp, Scheme, ML, Haskell Id, Val Prolog XSLT C, Ada, Fortran Perl, Python, Ruby, PHP Smalltalk, Java, C++

Obs.: Uma linguagem pode ser de mais de um tipo.

Declarativa x Imperativa
Declarativa Foco: o que o computador deve fazer Mais alto nvel Imperativa Foco: como o computador deve fazer Mais eciente

Linguagens Funcionais

Denio recursiva de funes Programa: funo que mapeia entrada na sada Funes escritas como funes mais simples

Linguagens Dataow (uxo de dados)


Computao como o uxo de tokens entre funes (nodes) Modo inerentemente paralelo: nodes so ativados quando a informao chega nodes podem operar em paralelo

Linguagens Lgicas

Inspirao: lgica de predicados Computao: provar teoremas a partir de regras

Linguagens von Neumann


Mais familiar: modelo de C Computao: modicao do valor de variveis Atribuies inuenciam a computao Computao por efeito colateral

Linguagens Scripting
Subconjunto das linguagens von Neumann nfase em juntar diferentes componentes Muitas desenvolvidas para ns especcos: bash nfase: facilidade de criao de prottipos facilidade de expresso no lugar de desempenho

Linguagens OO

Similares a linguagens von Neumann Computao: interao entre objetos Objetos: estado interno e rotinas para control-lo

Exemplo - C
MDC - von Neumann: Para computar o MDC de a e b, primeiro verique se eles so iguais. Se forem, retorne um e pare. Caso contrrio, substitua o maior pela sua diferena e repita.
int gcd(int a, int b) { while (a != b){ if (a > b){ a = a-b; } else{ b = b-a; } } return a; }

Exemplo - Scheme
MDC - Funcional MDC de a e b denido como: (1) a quando a e b forem iguais (2) o MDC de b e a-b quando a for maior que b (3) o MDC de de a e b-a quando b for maior que a Para computar o MDC para um par de nmeros, repita, expanda e simplique essa denio at que termine
(define gcd (lambda (a b) (cond ((= a b) a) ((> a b) (gcd (- a b) b)) (else (gcd (- b a) a)))))

Exemplo - Prolog
MDC - Lgico A proposio MDC(A,B,G) verdadeira quando (1) A, B e G forem iguais (2) A maior que B e existe um nmero C tal que C A-B e MDC(C,B,G) verdade (3) A menor que B e existe um nmero C tal que C B-A e MDC(C,A,G) verdade Para computar o MDC de dois nmeros, procure pelo nmero G para o qual essas regras permitam provar que MDC(A,B,G) verdadeiro
gcd(A,B,G) :- A = B, G = A. gcd(A,B,G) :- A > B, C is A-B, gcd(C,B,G). gcd(A,B,G) :- B > A, C is B-A, gcd(C,A,G), gcd(A,B,G).

Compilao
Cdigo fonte

Compilador
Entrada
Compilao x Execuo Compilador: programa Vantagem: desempenho Decises feitas na compilao no precisam ser feitas na execuo

Programa

Sada

Interpretao
Cdigo fonte Entrada

Interpretador

Sada

Interpretador: mquina virtual Execuo do cdigo fonte em conjunto com a entrada Vantagem: exibilidade Cdigo pode gerar novo cdigo em tempo de execuo

Caso Prtico
Cdigo fonte
Compilao: tradutor complicado Interpretao: tradutor simples Simples = transformao mecnica substituio de smbolos

Tradutor
Programa Intermedirio Entrada

Mquina Virtual

Sada

Pr-Processamento
Cdigo fonte

Pr-processador
Cdigo fonte alterado
Remove comentrios e macros Pode remover pedaos do cdigo: compilao condicional: Diferentes verses de um programa a partir do mesmo cdigo

Linker
Cdigo fonte

Compilador
Cdigo de mquina incompleto Bibliotecas

Linker
Cdigo de mquina

Converso para Assembler


Cdigo fonte

Compilador
Cdigo assembler

Assembler
Cdigo de mquina

Traduo
Cdigo fonte

Tradutor
Cdigo fonte em outra linguagem

Bootstrapping
Compiladores escritos na linguagem que eles foram feitos para compilar Como compilar o compilador pela primeira vez? Bootstrapping: Implementao simples: interpretador Incrementos sucessivos

Pascal
Compiladores para Pascal eram criados usando as seguintes ferramentas: Compilador Pacal, escrito em Pascal: gera uma sada intermediria chamada P-code O prprio compilador traduzido em P-code Um interpretador de P-code escrito em Pascal

Pascal
Criando o compilador: Traduo (manual) do interpretador de Pcode para uma linguagem disponvel Usa-se o interpretador para rodar o compilador Compila-se o cdigo do compilador o compilador interpretado

Outras formas de compilao


Compilao de linguagens interpretadas: Gerao de cdigo extra que quase um interpretador Compilao dinmica ou just-in-time Compilao imediatamente antes da execuo do cdigo Linguagens que permitem gerao de cdigo em tempo de execuo Byte-code de Java Micro-cdigo: Linguagem assembler interpretada por um cdigo de mquina chamado micro-cdigo

Ferramentas auxiliares:
Debuggers Editores Vericadores de estilo: anlise sinttica/semntica Controle de congurao e dependncias Prolers

IDE
Integrated Development Environment Integram diversas ferramentas Ex.: Eclipse, XCode, MS Visual Studio As vezes so essenciais para a linguagem: Ex.: Smalltalk

Exemplo

Viso Geral: Compilao


uxo de caracteres Fluxo de tokens Parse tree rvore de sintaxe abstrata Forma intermediria Linguagem alvo Linguagem alvo modicada

Scanner (anlise lxica) Parser (anlise sinttica) Anlise semntica e gerao de cdigo intermedirio Otimizao independente da mquina Gerao do cdigo Otimizao dependente da mquina Tabela de Smbolos
Front end

Back end

Anlise Lxica e Semntica


Relembrando o MDC em C:
int main() { int i = getint(), j =getint(); while (i != j){ if (a > b) i = i -j; else j = j - i; } putint(i) }

Anlise Lxica e Semntica


Scanning e parsing: reconhecer a estrutura do programa no esto interessados no signicado Scanner leitura caracteres e agrupamento em smbolos Smbolos: menor unidade signicativa do programa

Anlise Lxica
Tokens do MDC:
int ) { = j ) main ; if i ; ( ) while ( i } ) , ( i j ; { j i > ; } { j i > ; } int = != j else i j ) j = ) i = i getint ( getint (

putint (

Principal tarefa do analisador lxico: reduzir nmero de smbolos para anlise sinttica

Anlise Sinttica
Parsing: gerao da parse tree construes de alto nvel em funo de suas partes construes de alto nvel = funes, expresses raiz da rvore: programa Utilizao de gramticas de contexto livre Regras: construo -> expanso

Exemplo: While em C
iteration-statement statement

while ( expression ) statement

compound-statement

{block-item-list-opt} block-item-list-opt block-item-list block-item-list-opt block-item-list block-item block-item-list block-item-list block-item block-item declaration block-item statement
compound-statement

Anlise Semntica
Descobrir signicado no programa Reconhecimento de ocorrncia mltipla de smbolos Ao que cada ocorrncia do smbolo se referencia Identicao dos tipos e vericao de consistncia Tabela de smbolos: auxilia o analisador

Anlise Semntica Exemplo em C


Anlise semntica em C verica se: todo identicador declarado antes de ser utilizado um identicador utilizado num contexto inapropriado chamadas de funes utilizam o nmero e tipos corretos para os argumentos nomes utilizados nos ramos de um funes possuem o
return switch

so corretos
void)

correto (se no forem

Anlise Semntica
Nem todas regras semnticas podem ser aplicadas em tempo de compilao: compilador inclui vericaes em tempo de execuo para essas regras Semntica esttica: vericvel em tempo de compilao Semntica dinmica: vericvel em tempo de execuo

Anlise Semntica
Exemplo de vericaes dinmicas (em algumas linguagens): variveis nunca so utilizadas numa expresso se no possurem um valor Ponteiros nunca so de-referenciados a no ser que apontem para um objeto vlido ndices de vetores esto dentro de limites permitidos Operaes aritmticas no causam overow

Anlise Semntica
rvore sinttica: formada atravs da remoo de ns articiais na parse tree ns so anotados: atributos

program := (5) call (3) (6) :=

Exemplo
while call (3) (5) (6) > (5) (6) := (5) (5) (6) if call (4) (5) := (6) (6) (5)

Index Smbolo Tipo 1 2 3 4 5 6 void int getint putint i j tipo tipo func: (1)->(2) func: (2)->(1) (2) (2)

Gerao de Cdigo
Objetivo: gerar cdigo a partir da rvore Algoritmo: percorrer a tabela de smbolos e atribuir localizao para as variveis percorrer a rvore e gerar comandos

Otimizao de Cdigo

Diminuio do tempo de execuo Diminuio do consumo de memria Dependente ou independente da arquitetura/processador

Sintaxe
Linguagens de computao precisam ser precisas Especicao sem ambiguidade da: forma (sintaxe) signicado (semntica) Veremos sintaxe

Exemplo
Numerais: representao de nmeros
digit -> 0|1|2|3|4|5|6|7|8|9 Digit: bloco de construo de nmeros

Nmeros: sequncia de digits comeando por um numeral diferente de zero:


non-zero_digit -> 1|2|3|4|5|6|7|8|9 natural_number -> non_zero_digit digit*

Sequncia de caractere: sem signicado semntico

Especicando Sintaxe
Especicao formal de sintaxe: requer regras Construo a partir de caracteres individuais Construo de smbolos: 1. Concatenao 2.Alternncia 3.Kleene closure (repetio) Restante da sintaxe: recurso

Especicando Sintaxe
Conjunto regular: denido pelas trs regras Conjuntos regulares: criados por expresses regulares Conjuntos de strings que podem ser formados por conjuntos regulares + recurso Linguagem livre de contexto (LLC) LLC: gerada por uma gramtica livre de contexto Linguagem = linguagem formal linguagem de programao

Tokens
Unidades de construo de um programa: menor conjunto de caracteres com signicado Podem ser de diferentes tipos: palavras chaves identicadores smbolos constantes Podem ser denidos por apenas um caractere Exemplo: operadores

Exemplo: C
100 tipos de tokens 37 palavras chaves: double, if, return ... identicadores: minha_variavel, seu_tipo nmeros inteiros: 0223, 0x1f2, nmeros em ponto-utuante: 432e-2 caracteres: `a, b string literals: test punctuators: +, [ , ||, *= formas de comentrio

Expresses Regulares
Usadas para especicar tokens Uma expresso regular :
1. um caractere 2. uma string vazia = 3. duas expresses regulares uma do lado da outra = concatenao 4. duas expresses regulares separadas por | = alternncia 5. uma expresso regular seguida de

= concatenao por repetio

Exemplo
Sintaxe de constantes numricas: token = number
number integer real

(-|+|) (integer|real) digit digit

integer exponent | decimal (exponent|) digit(. digit|digit .)digit (e|E)(+|-|)integer

decimal

exponent digit

0|1|2|3|4|5|6|7|8|9

Forma til de denir strings

Expresses Regulares: Outros Usos


grep, emacs

Usada em diversas ferramentas:

Suporte em algumas linguagens: Perl, Python, Ruby Extenses: zero ou mais ocorrncias qualquer coisa que no seja espao

Gramticas Livre de Contexto (GLC)


Expresses regulares no denem construes aninhadas Exemplo:
expr op

id | number | - expr | ( expr ) | expr op expr

+ | - | * | /

Construo denida a partir dela mesmo

GLC
Smbolo = pode ter a forma de Regras de GLC: produo Smbolos a esquerda: variveis ou no-terminais Vrias produes para uma mesma varivel Smbolos que geraro uma derivao: terminais no podem aparecer na esquerda Linguagem de programao: terminais = tokens Ponto de partida: terminal na esquerda da 1a produo

Backus-Naur Form (BNF)


Notao para GLC No inclui e parnteses Extended Backus-Naur Form (EBNF) Inclui e parnteses Pode incluir +: 1 ou mais repeties

EBNF = BNF
id_list

id (, id)

= =

id_list id_list

id id_list , id

BNF tem o mesmo poder de expresso do EBNF!


op

op

+ | - | * | /

op op op

* /

Derivao e Parse Tree


GCL mostra como gerar strings sintaticamente vlidas: 1. Comece com um smbolo inicial 2. Escolha uma produo com o smbolo inicial na esquerda 3. Substitua o smbolo inicial com o lado direito da produo 4. Agora escolha uma varivel A da string resultante, escolha uma produo P com A no seu lado esquerdo 5. Substitua A pelo lado direito de P 6. Repita at que no sobre nenhuma varivel

Exemplo
Gerar a string: slope * x + intercept
expr expr op expr expr op id expr + id expr op expr + id expr op id + id expr * id + id id * id + id (slope) (x) (intercept)
expr expr expr op

BNF

id number expr op expr

+ | - | * | /

deriva

Derivao
Derivao: Sequencia de substituies que demonstram como chegar num determinado token Forma sentencial: linhas da derivao Sada: ltima forma sentencial que s possui terminais

Parse Tree
Representao grca de uma derivao
expr expr expr op * op expr + id (x) expr expr expr op expr op + expr id (intercept)

id (slope)

id id * expr (intercept) (slope) id (x)

GLC ambgua: permite criao de mais de uma parse tree para uma dada string

Parse Tree
Para uma dada linguagem: innitas gramticas possveis Porm, algumas gramticas so mais teis que outras Evitar gramticas ambguas Smbolos inteis: Variveis que no podem gerar terminais Terminais que no podem aparecer em nenhum resultado de derivao

Construo de Gramticas
Critrios no projeto de gramticas para uma linguagem de programao: Gramtica deve reetir estrutura interna do programa (facilita compilao) Deve ser facilmente parsed

Exemplo
Expresses aritmticas: uso da gramtica para reetir associatividade e precedncia Associatividade: operadores so agrupados da esquerda para direita Precedncia: multiplicao antes da soma

Exemplo
term | expr add_op term term factor | term mult_op factor factor id | number | -factor | (expr) add_op + | mult_op * | /
expr

No ambgua Captura precedncia a associativade

Exemplo Derivando 10-4+3


expr expr add_op + term factor number (3)
expr term | expr add_op term term factor | term mult_op factor factor id | number | -factor | (expr) add_op + | mult_op * | /

expr add_op term term factor number (10) factor number (4)

Exemplo Derivando 3+4*5


expr expr term factor number (3) op + term term mult_op factor number (4) * factor number (5)
expr term | expr add_op term term factor | term mult_op factor factor id | number | -factor | (expr) add_op + | mult_op * | /

Exerccios - Calculadora
Tokens:
assign := plus + minus times * div / lparen ( rparen ) id letter (letter|digit) except for read and write number digit digit | digit(.digit|digit.)digit comment /* (non-*|* non-/) */ | // (non-newline) newline

Parte II
Elementos de Linguagens de Programao

Introduo
Primeiras linguagens: Separao cdigo/mquina Atualmente: Facilidade de programao Necessidade de tipos de abstrao Nomes, controles, tipos, rotinas e classes Decises de projeto de linguagens

Nomes, Unies e Escopo

Nomes
Nome = mnemnico Maior parte das linguagens: identicadores Tokens alfa-numricos (+ alguns outros smbolos) Permitem o programador referenciar variveis, constantes, operaes, tipos, Programador no precisa saber conceitos de baixo nvel como o endereo de uma varivel

Nomes e Abstrao
Abstrao: processo que o programador utiliza para associar nomes a fragmentos de cdigo Fragmento: pensado em termos da funo que exerce no lugar de como ele exerce essa funo Reduo de complexidade: informaes irrelevantes cam escondidas Rotinas: abstraes de controle Classes: abstraes de dados

Tempo de Unio
Unio: associao entre duas coisas Neste caso: nome / o que nomeado Tempo de Unio: instante em que uma unio criada tempo em que qualquer deciso de implementao feita

Tempos de Unio
Projeto: estruturas de controle, tipos, ... Implementao: preciso dos tipos, I/O, ... Escrita do programa: algoritmos, estruturas de dados, ... Compilao: mapeamento em cdigo de mquina, ... Link: resoluo de nomes de diferentes mdulos Carregamento: momento que o sistema operacional carrega o programa para memria Execuo: unio de valores para variveis, ...

Unio: Esttica x Dinmica


Unio esttica: antes da execuo Unio dinmica: durante a execuo Linguagens compiladas: decises sobre unies ocorrem mais cedo maior ecincia (ex. vetor)

Tempo de Vida de Objetos


Diferena entre: nome e objetos a que eles se referem Eventos chaves: Criao de objetos Criao de unies Referncias para variveis, tipos, ... Desativao e reativao de unies Destruio de unies Destruio de objetos

Tempo de Vida de Objetos


Perodo entre criao de destruio da unio/objeto: Tempo de vida da unio/objeto Tempo de vida da unio Tempo de vida do objeto

Ex.: Passagem de valores por referncia Tempo de vida da unio nome de parmetro/ valor menor que o do objeto Ex.: Contedo do ponteiro deletado

Mecanismos de Alocao
Tempo de vida de objetos est associado ao mecanismo utilizado para alocar o objeto: Esttico: endereo constante Stack: alocao LIFO (last in - rst out) Heap: alocao em momentos arbitrrios

Alocao Esttica
O que alocado estaticamente: Variveis globais Instrues do programa Constantes numricas e literais Variveis locais estticas Tabelas auxiliares geradas pelo compilador Armazenadas em memria s de leitura

Alocao Esttica
Constantes de tempo de compilao Possuem nome Expresso deve conter apenas outras constantes e funes padres Podem alocadas estaticamente Constantes de tempo de elaborao Podem depender de valores em tempo de execuo No so estticas So variveis cujo valor no podem ser alterado

Alocao Esttica de Variveis Locais


Variveis locais: criadas quando sua subrotina chamada destrudas quando a subrotina retorna Cada chamada: nova instncia da varivel local Se a linguagem no permite recurso: alocao esttica (pelo compilador) Ex.: Fortran (antes do Fortran 90)

Dados de uma Subrotina


Chamada de uma subrotina/funo: Variveis locais Constantes de tempo de elaborao Argumentos e valores de retorno Usualmente mantido em registradores Temporrios: usados em clculos complexos Misc.: endereo de retorno, informao de debug

Alocao no Stack
Aninhamento de subrotinas: permite criao de espao no stack para variveis locais Cada instncia de uma subrotina: quadro Argumentos a serem passados para uma subrotina: no topo do quadro outros dados no tem uma ordem especca

Alocao no Stack
sp fp
Subrotina D
procedure C

Argumentos para rotinas Temporrios

D; E procedure B if ... then B else C

Subrotina C Variveis Locais Misc. Endereo de retorno

procedure A B -- main program A

Subrotina B Subrotina B Subrotina A

fp
(quando C est sendo executado)

sp: stack pointer, fp: frame pointer

Alocao no Stack
Manuteno do contedo do stack responsabilidade da rotina de chamada Rotina de chamada: cdigo executado imediatamente antes e aps da rotina propriamente dita

Alocao no Stack
Localizao de um quadro: no determinado Comprimento do quadro: determinado estaticamente Determina o offset Offset de coisas dentro do quadro: usualmente podem ser determinadas estaticamente Frame pointer (apontador para o quadro): compilador pode faze-lo apontas para uma posio conhecida dentro do quadro

Alocao no Stack
Acesso a variveis locais de um quadro: soma de um valor ao FP Variveis locais, temporrios: offset negativo Argumentos e valor de retorno: offset positivo Ficam no quadro de quem chama a rotina

Alocao no Heap
Regio de memria onde blocos podem ser arbitrariamente alocados e desalocados Necessrio para determinados objetos: Listas encadeadas, strings, listas e conjuntos Coisas que podem mudar de tamanho em tempo de execuo

Gerenciamento do Heap
Compromisso: velocidade x espao Espao: fragmentao interna e externa Interna: alocao de mais memria do que necessrio para um objeto Externa: blocos de um dado objeto so espalhados pela memria Diversos algoritmos para lidar com esse problema

Coletor de Lixo
Alocao de memria no Heap: necessidade de alguma ao no programa Desalocao de memria no Heap: C, C++: necessidade de ao Outras linguagens: desalocao automtica Biblioteca de tempo de execuo: coletor de lixo: denido pela linguagem

Coletor de Lixo
Argumentos contra: simplicidade de implementao velocidade de execuo Argumentos a favor: diminuio de erros e bugs facilidade de programao

Escopo
Denio: regio textual do programa em que uma unio est ativa Escopo esttico: escopo determinado em tempo de compilao Escopo dinmico: escopo s pode ser determinado em tempo de execuo Conjunto de unies ativas: conjunto de referncia determinado pelas regras de escopo da linguagem

Exemplo - C
Entrada de uma rotina: criao de um novo escopo criao de unies para objetos locais desativao de unies globais que tenham o mesmo nome que objetos globais Na sada de uma rotina: destruio de unies locais reativao de unies globais previamente desativadas

Escopo Esttico
Escopo determinado completamente a partir do cdigo Usualmente: unio atual para um nome = declarao no bloco mais prximo do uso do nome Regras de escopo simples: s existem variveis globais (1a verso de Basic) s existem variveis globais e locais (Fortran) Normalmente: necessidade de regras mais complicadas

Rotinas Aninhadas
Aninhamento de rotinas: permitido em diversas linguagens Pascal, Ada, Python, Scheme, Lisp C/C++: No permitido para funes Mas, escopos podem ser aninhados

Rotinas Aninhadas
Declaraes feitas num bloco so invisveis em outros blocos - escopo do tipo Algol Regra do escopo aninhado mais prximo: um nome introduzido por uma declarao visvel no escopo em que foi declarado e qualquer escopo aninhado interno a no ser que o nome seja ocultado por uma declarao com mesmo nome num dos escopos aninhados

Rotinas Aninhadas
Como achar o objeto associado a um nome: Procura pela declarao com o nome no escopo mais interno em utilizao Se existe uma declarao, ela utilizada para determinar o objeto Seno, a busca feita no escopo imediamente externo

Exemplo
int main() { int i = 0; { int i = 1; /* i == 1 */ { int i = 2; /* i == 2 */ } /* i == 1 */ } /* i = 0 */ }

Rotinas Aninhadas
Objetos pr-denidos pela linguagem: tipos, operadores matemticos, ... Eles so denidos num escopo mais externos, acima do escopo onde variveis globais so declaradas

Resoluo de Escopo
Unio nome-objeto que est oculta por uma declarao aninhada com mesmo nome: Como acessar esse nome? Operadores de resoluo de escopo: qualicador do nome: dene o escopo em que o nome foi declarado Exemplo: C++ ::x -> x declarado no escopo global

Ordem de Declarao
Suponha o objeto X declarado no bloco B O escopo de X inclui a parte de B antes da declarao de X? Obs.: Exigir declaraes no incio do bloco no impedem o problema... Diferentes linguagens, diferentes regras

Pascal
Declarao vale para todo o bloco (escopo em blocos)
const N = 10; ... procedure foo; const M = N; (*static semantic error*) ... N = 20; (*declarao local, esconde o N global*)

Pascal
const N = 10; ... procedure foo; const M = N; var A : array [1..M] if integer; N : real;

C#
Tambm utiliza escopo em blocos
class A { const int N = 10; void foo() { const int M = N; // uso do N interno antes da declarao const int N = 20; ...

Python
Sem declaraes de variveis Variveis na rotina S so aquelas que aparecem nas expresses da rotina S Variveis no-locais so apenas de leitura e precisam ser explicitamente importadas

Python
a = 1 def f(): print a # 1 def g(): print a # Erro a = 2 def h(): global a a = 2 print a # 2

Leitura da varivel global Ok Nome a agora local Altera o valor da varivel global

Declarao e Denio
Tipos e rotinas recursivos e linguagens que demandam declarao antes de utilizao Como duas declaraes podem aparecer antes uma da outra?
struct empregado { struct gerente *chefe; struct empregado *proximo_empregado; ... }; struct gerente { struct empregado *primeiro_empregado; ... };

Declarao e Denio
Soluo de C/C++: distino denio x declarao Declarao: dene o nome e seu escopo Denio: detalhes de implementao Em alguns casos: declarao pode servir tambm como denio

C
struct gerente; /* Declarao!*/ struct empregado { struct gerente *chefe; struct empregado *proximo_empregado; ... }; struct gerente { /* Definio!*/ struct empregado *primeiro_empregado; ... };

Mdulos
Projetos grandes: Como dividir o trabalho entre diversos programadores? Modularizao: diviso do cdigo em partes independentes Ocultamento de informao: esconder algoritmos de partes do cdigo onde so desnecessrios reduz a quantidade de cdigo necessria para o entendimento de uma parte do programa Boa modularizao: interface entre mdulos simples parte mutvel do cdigo ocultada dentro de um mdulo reduz quantidade de conitos de nomes

Encapsulamento de Dados e Rotinas


Rotinas aninhadas: ocultamente de informao limitado: objetos limitados ao tempo de vida da rotina Variveis estticas: permite: rotinas tenham memria permite: abstrao de apenas uma nica rotina no permite: interfaces que precisam de mais de uma rotina Necessidade de uma nova construo nas linguagens: mdulo

Mdulos como Abstraes


Mdulos: coleo de objetos: rotinas, variveis, tipos, ... Encapsulado de maneira que: 1. Objetos dentro do mdulo enxergam uns aos outros 2. Objetos dentro do mdulo so invisveis fora do mdulo a no ser que explicitamente exportados 3. (opcional) objetos fora do mdulo so invisveis a no ser que explicitamente importados Regras denem visibilidade dos objetos, mas no o seu tempo de vida

Mdulos em Diferentes Linguagens


Package: Ada, Java, Perl Module: Python Namespace: C++, C#, PHP

Exemplo: Stack (Modula-2)


CONST stack_size = ... TYPE element = ... ... MODULE stack; IMPORT element, stack_size; EXPORT push, pop; TYPE stack_index = [1..stack_size]; VAR s : ARRAY stack_index OF element; top : stack_index; PROCEDURE error; ... PROCEDURE push (elem : element); BEGIN IF top = stack_size THEN error; ELSE s[top] := elem; top := top + 1; END; END push; PROCEDURE pop () : element; BEGIN IF top = 1 THEN error; ELSE top := top - 1; RETURN d[top]; END; END pop; BEGIN top := 1; END stack;

VAR x, y : element; ... push(x); ... y := pop;

Import e Export
Possveis limitaes da exportao: variveis apenas de leitura tipos opacos: no podem ser manipulados Mdulos de escopo fechado: nomes precisam ser explicitamente importados Reduz conitos de nomes, facilita entendimento do cdigo Mdulos com escopo seletivamente abertos: Nome foo exportado pelo mdulo A automaticamente visvel no mdulo B como A.foo (ou foo se B importar explicitamente o nome) Ada, Java, C# e Python Lista de importao: documenta a interface entre partes de um programa

Mdulos como Gerentes


Exemplo anterior: mdulos denem apenas uma abstrao Mdulo dene apenas uma pilha Vrias pilhas: mdulo como gerente Gerencia o tipo pilha Subrotinas: criar e destruir o tipo Subrotinas: argumento denindo stack

Exemplo: Gerente
CONST stack_size = ... TYPE element = ... ... MODULE stack_manager; IMPORT element, stack_size; EXPORT stack, init_stack, push, pop; TYPE stack_index = [1..stack_size]; stack = RECORD s : ARRAY stack_index OF element; top : stack_index; END; PROCEDURE init_stack(VAR stk : stack); BEGIN stk.top := 1; END init_stack; PROCEDURE push (VAR stk : stack, elem : element); BEGIN IF stk.top = stack_size THEN error; ELSE stk.s[stk.top] := elem; stk.top := stk.top + 1; END; END push; VAR A, B : stack; var x, y : element; ... init_stack(A); init_stack(B); ... push(A, x); ... y := pop(B); PROCEDURE pop (VAR stk : stack) : element; BEGIN IF stk.top = stack_size THEN error; ELSE stk.top := stk.top - 1; RETURN stk.s[stk.top]; END; END pop; END stack_manager;

Mdulos como Tipos


Outra possvel soluo: mdulos denem tipos Mdulo de tipo: permite a declarao de um nmero arbitrrio Rotinas pertencem ao mdulo

Exemplo: Stack (Euclid-2)


const stack_size = ... type element = ... ... type stack = module imports (element, stack_size) exports (push, pop) type stack_index = 1..stack_size; var s : array stack_index of element top : stack_index procedure push(elem : element) = ... function pop returns element = ... ... initially top := 1 end stack

VAR A, B : stack; var x, y : element; ... A.push(x) ... y := B.pop

Orientao a Objetos
Linguagens modernas: classes = mdulos como tipos + herana Herana classes denidas como extenses ou renamento de classes que j existem objetos podem herdar comportamento de outros objetos Facilita reuso de cdigo

Orientao a Objetos
Cada instncia da classe ou mdulo A: cpia separada das variveis variveis so apenas visveis quando executando uma das rotinas de A Visveis para outras rotinas se A passada como argumento

Exemplo
class stack { ... bool deeper_than(stack other) { return (top > other.top); } ... } ... if (a.deeper_than(B)) ...

Mdulos e Classes
Classes no substituem mdulos em todos os casos Exemplo: Jogo Hierarquia: personagens, prdios, objetivos, ... Mdulos: diviso do projeto em sub-sistemas (no requerem herana) Linguagens com classes e mdulos: C++, Java, C#, Python, Ruby, ...

Escopo Dinmico
Associao entre nome e objeto determinado em tempo de execuo: ordem de chamada das rotinas nica regra: unio para um nome aquela encontrada mais recentemente durante a execuo do programa e ainda no destruda Linguagens: APL, Snonbol, TeX e Perl Vericao de tipos: s possvel em tempo de execuo

Escopo Dinmico: Exemplo


int x = 0; int f() { return x; } int g() { int x = 1; return f(); }

Escopo esttico: - Retorna: 0 Escopo dinmico - Retorna: 1 f() enxerga associao mais recente

Escopo Dinmico: Exemplo


n : integer procedure first n := 1 procedure second n : integer first() n := 2 if read_integer() > 0 second() else first() write_integer(n)

Escopo esttico: - Exibe: 1 Escopo dinmico - valor depende do valor lido por read_integer() - Se maior que zero: exibe 2 - Se menor ou igual a zero: exibe 1

Escopo Dinmico
Ponto favorvel: facilita modicao de rotinas Exemplo: funo para imprimir inteiros em qualquer base:
begin -- nested block print_base : integer = 16 -- hexadecimal print_integer(n)

Caso padro: decimal Escopo dinmico: modicao durante execuo

Implementao do Escopo (Esttico)


Tabela de smbolos: dicionrio: nome -> informao operaes: nova entrada: unio nome-objeto procura: busca de informao de um nome enter_scope e leave_scope: visibilidade Nada removido: tabela mantida completa

Signicado de Nomes
At agora: relao um para um entre nome e objeto Na realidade: nome pode referenciar mais de um objeto objeto pode ter mais de um nome

Aliases (Apelidos)
Quando dois nomes apontam para o mesmo objeto: C: unio Ponteiros Passagem de variveis por referncia Em geral: tornam o cdigo mais confuso

Exemplo
int a, b, *p, *q; ... a = *p; *q = 3; b = *p;

Complicao desnecessria para o compilador Atribuio em a faz com que *p seja trazido para um registrador Compilador gostaria de deixar *p em um registrador (por causa da atribuio de b) Mas no consegue fazer isso pois no sabe se p e q apontam para o mesmo objeto

Sobrecarga

Quando um nome referencia mais de um objeto Exemplo: operador + em C

Exemplo Ada
declare type month is (jan, feb, mar, apr, may, jun, jul, aug, sep, oct, nov, dec); type print_base is (dec, bin, oct, hex); mo : month; pb : print_base; begin mo := dec; -- mes dezembro pb := oct; -- a base oct print (oct); -- erro!

Exemplo C++
struct complex { double real, imaginary; }; enum base {dec, bin, oct, hec}; int i; complex x; void print_num(int n){... void print_num(int n, base b){... void print_num(complex c){... print_num(i); print_num(i, hex); print_num(x);

Redenio de Operadores
Sobrecarga dos operadores aritmticos Ada, C++, C#, Fortran90, Python Sintaxe alternativa para o operador: Ada: A+B -> +(A, B) C++: A+B -> operator+(A, B) ou A.operator+(B)

Exemplo C++
class complex{ double real, imaginary; ... public: complex operator+(complex other){ return complex(real+other.real, imaginary+other.imaginary); } ... }; ... complex A, B, C; ... C = A + B;

Sobrecarga, Polimorsmo e Coero


Para nome de rotinas: Sobrecarga x Polimorsmo x Coero Mecanismos para: passar argumentos de diferentes tipos para rotinas Diferena sinttica

Exemplo
Clculo do menor valor entre dois nmeros inteiros ou em pontos-utuante

Ada:
function min(a, b : integer) return integer is ... function min(a, b : real) return real is ...

Sobrecarga: compilador chama a funo adequada para o tipo

C:
double min(double x, double y){ ...

Coero: compilador converte de int para double

Coero
Processo pelo qual o compilador converte um tipo em outro Diferente regras em diferentes linguagens: Ada: no faz coero de tipo, a menos de constantes C e Pascal: coero de inteiros para ponto utuante C++: regras de coero podem ser estendidas pelo programador

Polimorsmo
Mesma rotina, vrios tipos de argumentos SEM converso Termo: pode assumir vrias formas Aplicado a dados e rotinas Tipos precisam ter caractersticas em comum

Polimorsmo
Polimorsmo paramtrico: cdigo aceita um tipo ou conjunto de tipos como parmetros Encontrado em: linguagens orientada a objetos (herana) Polimorsmo de subtipo: cdigo feito para funcionar para um tipo T, mas o programador por denir extenses e renamentos Implcito: tipo no denido (Lisp, Python) Explcito: tipo denido = programao genrica (C++, Java, C#)

Polimorsmo: Implementao
Programao genrica (paramtrico explcito): Geralmente: mltiplas cpias do cdigo, uma para cada tipo Herana (subtipo): nica verso do cdigo, informao extra sobre representao dos objetos includa Paramtrico implcito: pode ser feito das duas maneiras

Polimorsmo: Implementao
Linguagens que fazem vericao de tipo em tempo de execuo: C++, Java, C#: oferecem herana e programao genrica Smalltalk, Objective-C, Python, Ruby: apenas um mecanismo que fornece ambos tipos de polimorsmo

Exemplo Programao Genrica


Ada
generic type T is private; with function <(x, y : T) return Boolean; function min(x, y : T) return T is begin if x < y then return x; else return y; end if; end min; function string_min is new min(string, <); function date_min is new min(date, date precedes);

Exemplo Polimorsmo Param. Implcito


Python
def min(x, y): if x<y: return x else: return y a = 1 b = 2 c = complex(1,1) b = min(a, b) # b=1 a = min(a, c) # ERRO

Unio de Ambientes de Referenciamento


Referncia para rotinas: Rotinas podem ser passadas como referncias para outras rotinas Quando a regra de escopo deve ser aplicada: Quando a referncia criada? Quando a rotina chamada?

Exemplo Escopo Dinmico


type person = record ... age : integer ... threshold : integer people : database function older_than_threshold(p : person):boolean return p.age theshold; procedure print_person(p : person) ... -- garante que o comprimento da linha (line_length) no ultrapassado. procedure print_selected_record(db : database; predicate, print_routine : procedure) line_length : integer if device_type(stdout) = terminal line_length := 80 else line_length := 132 foreach record r in db if predicate(r) print_routine(r) -- programa main ... threshold := 35 print_selected_records(people, older_than_threshold, print_person)

Exemplo Escopo Dinmico


Shallow bind: ambiente de referncia criado quando a funo chamada Funciona para print_routine Deep bind: ambiente de referncia criado quando a funo passada como parmetro til para older_than_threshold

Fechamento de Rotinas
Implementao de Deep binding: criao explcita do conjunto de referncia unio desse conjunto com a referncia para funo Conjunto + referncia = Fechamento Padro para escopo esttico

Deep Binding
program binding_example(input, output); procedure A(I : integer; procedure P); procedure B; begin writeln(I); end begin (* A *) if I > 1 then P else A(2, B); end; procedure C; begin end; begin (* main *) A(1, C); end.

B A I==2 p==B I==1 p==C

main program

Deep Binding
Impacto: variveis que no so nem locais nem globais Objetos locais: fechamento no importa Objetos globais: nunca haver mais de uma verso

Funes de Primeira Classe


Funes de primeira classe: podem ser passadas como argumentos podem ser retornadas por uma funo podem ser atribudas a variveis Problema: Nome dura mais do que o escopo em que foi denido

Exemplo
def plus_x(x): return lambday:y+x plus_two = plus_x(2) print plus_two(2) # 4

Escopo de x? Tempo de vida do objeto?

Unlimited Extent
Objetos locais: tempo de vida com durao innita Memria s recuperada quando o sistema tiver certeza que o objeto no pode ser mais usado Coletor de lixo Limited extent: maior parte das linguagens imperativas Unlimited extent: scripts, C#, Smalltalk

Outros Mecanismos

No permitir rotinas aninhadas: C, C++ S rotinas de fora so de primeira classe: Modula-2

Fechamento de Objetos
Impedimento de rotinas aninhadas Problema: Impede a passagem de funes com contexto Alternativa em OO: objetos simples

Exemplo
interface IntFunc{ public int call(int i); } class PlusX implements IntFunc { final int x; PlusX(int n) {x = n;} public int call(int i) {return i+x;} ... IntFunc f = new PlusX(2); System.out.println(f.call(3)); // 5

Fechamento de Objetos

Objeto que faz o papel de uma funo e contexto: Object closure, function object, functor

Exemplo
class int_func { public: virtual int operator()(int i) = 0; }; class plus_x : public int_func { const int x; public: plus_x(int n) : x(n) { } virtual int operator()(int i){return i+x;} }; ... plus_x f(2); cout << f(3) << endl; // 5

Controle de Fluxo

Controle de Fluxo

Determinao da ordem em que as tarefas so executadas no cdigo Fundamental para quase todas linguagens

Mecanismos de Controle
Sequenciamento: ordem pr-denida Seleo: escolha entre duas partes do cdigo, dependendo de condies do tempo de execuo Iterao: pedao do cdigo repetido at que alguma condio seja satisfeita Abstrao de procedimento: encapsulamento de controles de uxo: procedimentos, mdulos

Mecanismos de Controle
Recurso: uma expresso escrita em funo de verses mais simples dela mesma Concorrncia: dois pedaos do programa executando ao mesmo tempo Controle de exceo: um pedao do cdigo executado e, caso ocorra erros, o uxo redirecionado para outra parte do cdigo No-determinao: ordenao no determinada (execuo em qualquer ordem leva ao resultado correto)

Avaliao de Expresso
Expresso: funo ou operador aplicado a um conjunto de argumentos operador: funes da linguagem com sintaxe simplicada Exemplos: my_func(A, B, C) a+b -c

Operadores
Prexo: op a b, op(a, b), (op a b) Inxo: a op b Suxo: a b op Usualmente: Prexo: funes e operadores unitrios Inxo: operadores binrios

Notao Polonesa

Utilizada em Lisp para funes e operadores (* (+ 1 3) 2) (append a b c my_list)

Notao Mixx
Utilizada em Smalltalk Inxo para todas as funes
myBox displayOn: myScreen at: 100@50

Chama o mtodo displayOn: at: com argumentos myScreen e 100@50

Notao por Inxo em C

a = b != 0 ? a/b : 0;

Posxo
Comum em algumas calculadoras Aparece ocasionalmente em algumas linguagens Exemplo: ++ e -- em C++

Precedncia
Dene quais operadores so executados primeiro na ausncia de parnteses Detalhes mudam de linguagem para linguagem Normalmente: regras tentam garantir que o resultado esperado encontrado

Associatividade
Dene como operadores com mesma precedncia so agrupados Comportamento mais uniforme para diferentes linguagens: Operadores aritmticos: associatividade pela esquerda Exponenciao: associatividade pela direita Recomendao: USE PARNTESES!

Atribuio
Linguagens funcionais: s tem expresses Atribuies: linguagens imperativas Mudana no valor de variveis Necessita de dois argumentos: valor referncia para varivel que armazenar Expresses: retornam um valor Statements: no retornam um valor

Referncias e Valores
C: d = a; a: se refere a um valor a = b +c; a: se refere a posio do valor Variveis em C: container com nome Linguagem com modelo de valor Variveis no lado direito e esquerdo de atribuies

l-values e r-values
l-value: o que aparece do lado esquerdo de uma atribuio r-value: o que aparece do lado direito

Exemplos

(f(a)+3)->b[c] = 2; g(a).b[c] = 2;

No trivial saber o que pode ou no ser l-value

Modelo de Referncia
Varivel: referncia para um valor
b := 2; c := b; a := b + c;

b referencia 2 c referencia 2 tambm passagem das referncias para o operador + a referencia o resultado da operao 2 imutvel Filosocamente: existe um nico 2 no programa, que referenciado por todas as variveis que possuem esse valor

Modelo de Referncia
Distino entre l-value e r-value explcita Toda varivel l-value Quando necessrio num r-value, ela de-refernciada converso implcita converso explcita Necessria a distino entre: referncias para mesmo valor Mesmo objeto? Temporariamente iguais?

Ortogonalidade
Meta ao se desenvolver uma linguagem de programao (ou mesmo programas) Features da linguagem podem ser combinadas em qualquer ordem Combinao consistente Principal princpio do projeto do Algol 68: No existem statements, apenas expresses

Exemplo
begin a := if b < c then d else e; a := begin f(b); g(c) end; g(d); 2 + 3; end

if .. then .. else: retorna o valor da sequencia statement list: valor de retorno da ltima funo: g(c)

C
Abordagem intermediria: distino entre statement e expresses Mas uma das classes de statement : expression statement: retorna um valor mas o jogo fora Exemplo: a = 4, retorna 4

Combinao de Operadores
Simplicao da sintaxe: a = a+1; == a += 1; Casos mais til:
b.c[3].d = b.c[3].d *e; b.c[3].d *= e; int j = index_fn(i); A[j] = A[j] + 1; A[index_fn(i)] += 1;

Outras combinaes: ++ e --

Atribuio Mltipla

a, b, c = 1, 2, 3; a, b = c, d; a, b, c = foo(d, e, f);

Inicializao de Varivel
Permitido por algumas linguagens Vantagens: inicializao de variveis estticas permite otimizao de alocao de variveis estticas pelo compilador Evita uso de variveis no-inicializadas Inicializao durante declarao

Inicializao: Vericao Dinmica


Variveis no inicializadas podem ser checados em tempo de execuo: Caso estejam no estado no-inicializdo: Erro Caso de variveis numricas: baixo custo computacional

Exigncia de Atribuio

Java e C# Varivel precisa ser atribuda antes de ser lida Por todos os caminhos do cdigo

Exemplo
int i; int j = 3; ... if (j > 0){ i = 2; } ... // valor de j no alterado aqui... if (j > 0){ System.out.println(i); // erro: i pode no // ter sido inicializao

Construtores
Linguagens OO Inicializao de variveis alocadas dinmicamente Chamada de uma rotina de construo C++: construo atribuio C# e Java: construo = atribuio

Ordenao dentro de Expresses


a - f(b) - c * d f(a, g(b), h(c)) Qual a ordem de avaliao? Importante saber: Se f(b) modicar d (efeito colateral) Velocidade de execuo Em geral: ordem no denida (permite otimizao)

Curto-Circuito
Usado em expresses booleanas Otimizao do cdigo Ex.: a < b and ( b < c) Se b for menor que c: a < b no executado Ex.: (a > b) or (b > c)

Curto Circuito
Pode reduzir tempo de execuo: if (condio_improvvel && funo_demorada()) Mas pode alterar a semntica:
p = my_list; while (p && p->key != val) p = p->next;

Exemplo
const MAX = 10; int A[10]; ... if (i >= 0 && i < MAX && A[i] > foo)...

if ( d != 0 && n/d > limiar) ...

Fluxo No Estruturado
Controle de uxo em assembler: saltos condicionais e no-condicionais Primeiras verses de Fortran:
if (A .lt. B) goto 10 ! .lt. < ... 10

10: statement label

Fluxo No Estruturado

Dcada de 70: programao estruturada Abolio do goto

Alternativas ao goto
Retornos de funo Erros e excees break continue

Sequenciamento
Determina a ordem das atribuies Lista de statements sequenciados: { e } begin e end

Seleo
If ... then ... else ... Algol: primeiro if
if condition then statement else if condition then statement else if condition then statement ... else statement

Seleo
Modula-2:
IF a = b THEN ... ELSIF a = c THEN ... ELSIF a = d THEN ... ELSE ... END

Lisp:

(cond ((= A B) (...)) ((= A C) (...)) ((= A D) (...)) (T (...)))

Curto-Circuito
Implementao: pulos no cdigo Condio no armazenada utilizada para controlar o uxo gerao de cdigo eciente para booleanos com curto-circuito

Sequenciamento
Case/Switch alternativa para if aninhados
CASE (*expressao*) OF 1: ... 2, 7: ... 3..5: ... 10: ... ELSE ... END

Sequenciamento
Case/Switch Variaes sintticas: srie de valores x nico valor default requerido x opcional

Sequenciamento
Case/Switch do C: pouco usual
switch (...) { case 1: ... break; case 2: ... case 7: ... break; case 3: ... case 4: ... case 5: ... break; default: ... break; }

Iterao
Repetio de tarefas similares Controle por enumerao: execuo de um cdigo para cada elemento de um conjunto nito Controle lgico: execuo at que uma condio lgica seja satisfeita

Repetio Controlada por Enumerao


Fortran 90
do i = 1, 10, 2 ... enddo

Modual 2
FOR i:= first to last by step DO ... END

Complicaes Semnticas

Loop for: apenas para iterao: implementao simples facilitador de enumerao

Complicaes Semnticas
Questes que denem forma da enumerao: 1. Pode-se sair do loop de alguma forma que no terminando a enumerao? Break 2. O que acontece quando modica-se variveis que afetam o critrio de parada dentro do loop? Critrio pr-computado 3. O que acontece quando o contador modicado dentro do loop? Normalmente no permitido 4. Pode-se ler o contedo do ndice aps o loop? Se sim, qual o seu valor? Diferentes solues: declarao dentro do loop, valor nal

For em C
for (i = first; i<= last; i += step) { ... }

=
{ i = first; while (i <= last) { ... i += step; } }

Iteradores
At agora: iterao sobre sequncias aritmticas Ideal: iterao sobre elementos de um conjunto nito Soluo: iteradores Clu, Python, Ruby e C# Objetos iteradores: Java, C++

Iteradores
for i in range(first, last, step): ...

Funo range - iterador Range: calcula o valor e o retorna para o loop Loop usa o valor e chama range novamente Range retoma a execuo do ponto em que parou Vantagem: separa mecanismo de enumerao do cdigo que o usa

Exemplo
class BinTree: def __init__(self): # construtor self.data = self.lchild = self.rchild = None # Outros mtodos: insert, delete, lookup, ... def preorder(self): # Iterador if self.data != None: yield self.data if self.lchild != None: for d in self.lchild.preorder(): yield d if self.rchild != None: for d in self.rchild.preorder(): yield d

Objetos Iteradores
C++, Java: no tem yield Soluo: guardar o estado da ltima iterao num objeto Objeto iterador

Exemplo
BinTree <Integer> myTree = ... ... for (Integer i : myTree) { System.out.println(i); }

=
BinTree <Integer> myTree = ... ... for (Iterator<Integer> it = myTree.iterator(); it.hasNext(); ) { Integer i = it.next(); System.out.println(i); }

class BinTree<T> implements Iterable<T>{ BinTree<T> left; BinTree<T> right; T val; ... // outros mtodos: insert, delete, lookup public Iterator<T> iterator(){ return new TreeIterator(this); } private class TreeIterator implements Iterator<T> { private Stack<BinTree<T>> s = new Stack<BinTree<T>>(); TreeIterator(BinTree<T> n) { if (n.val != null) s.push(n); } public boolean hasNext() { return !s.empty(); } public T next() { if (!hasNext()) throw new NoSuchElementException; BinTree<T> n = s.pop(); if (n.right != null) s.push(n.right); if (n.left != null) s.push(n.left); return n.val; } public void remove() { throw new UnsuppertedOperationException(); } } }

Iterando sem Iteradores


bin_tree *my_tree; tree_iter ti; ... for (ti_create(my_tree, &ti); !ti_done(ti); ti_next(&ti)){ bin_tree *n = ti_val(ti); ... } ti_delete(&ti);

Iterao Controlada Logicamente


Vericao de uma condio de parada lgica Duas opes: teste no incio teste no m

Recurso
Funo em funo dela mesmo No requer sintaxe extra Qualquer algoritmo iterativo pode ser reescrito recursivamente

Iterao x Recurso

Iterao -> linguagens imperativas Recurso -> linguagens recursivas

Exemplo
typedef int (*int_func) (int); int summation (int_func f, int low, int high) { int total = 0; int i; for (i = low; i <= high; i++) { total += f(i); } return total; }

1i10
typedef int (*int_func) (int); int summation (int_func f, int low, int high) { if (low == high) return f(low); else return f(low) + summation(f, low+1, high); }

f (i)

Exemplo
a gcd(a b, b) gcd(a, b) = : gcd(a, b a) 8 < , if a = b , if a > b , if b > a

int gcd(int a, int b){ if (a==b) return a; else if (a > b) return gcd(a-b, b); else return (a, b-a); }

int gcd(int a, int b){ while (a != b) { if (a > b) a = a-b; else b = b-a; } return a; }

Tail Recursion
Gerao de cdigo recursivo eciente Nenhuma computao realizada aps chamada recursiva Compilador consegue otimizar cdigo: Reuso de espao em memria

Exemplo
int gcd(int a, int b){ start: if (a==b) return a; else if (a > b){ a = a-b; goto start; } else { b = b-a; goto start; } }

Exemplo
Lisp
(define summation (lambda (f low high) (if (= low high) (f low) then (+ (f low) (summation f (+ low 1) high))))) ; then ; else

Pensando Recursivamente
Scheme
define fib (lambda (n) (cond ((= n 0) 1) ((= n 1) 1) (#t (+ (fib (- n 1)) (fib (- n 2)))))))

Problema: tempo exponencial!

Pensando Recursivamente
Lisp
(define fib (lambda (n) (letrec ((fib-helper (lambda (f1 f2 i) if (= i n) f2 (fib-helper f2 (+ f1 f2) (+ i 1))))) (fib-helper 0 1 0)))

Ordem de Avaliao: Aplicativa e Normal


At agora, argumentos so avaliados antes de serem passados para uma funo Alternativa: Passar argumentos no-avaliados S avaliar se for necessrio Avaliar antes: ordem aplicativa Avaliar depois: ordem normal

Ordem de Avaliao: Aplicativa e Normal


Ordem aplicativa: mais fcil de entender Ordem normal: pode gerar cdigo mais rpido Lazy evaluation Implementao: promessas: argumentos no avaliados Sintaxe: informar quais argumentos so lazy

Exemplo
(define naturals (letrec ((next (lambda (n) (cons n (delay (next (+ n 1))))))) (next 1))) (define head car) (define tail (lambda (stream) (force (cdr stream))))

(head naturals) => 1 (head (tail naturals)) => 2 (head (tail (tails naturals))) => 3

Tipos de Dados

Introduo

Funes de tipos: contexto para operaes limites semnticos para operaes

Sistema de Tipos
Mecanismo para denir tipos e associ-los a construes da linguagem Conjunto de regras para: equivalncia: quando dois valores de tipos diferentes so iguais compatibilidade quando valores de um tipo podem ser utilizados inferncia tipo do resultado de uma expresso com base nos seus tipos constituintes

Vericao de Tipo
Processo Vericao: programa obedece as regras de compatibilidade de tipo? Linguagens: fortemente tipadas: probem uso de uma operao em um objeto que no permitido por ela estaticamente tipadas: fortemente tipada + vericao durante compilao

Polimorsmo
Mesmo cdigo - diferentes tipos Pode (ou no) implicar vericaes de tempo de execuo Sistema de tipo dinmico: tipo implcito polimorsmo paramtrico implcito vericao em tempo de execuo Outros tipos de polimorsmo: pode ser vericado durante tempo de compilao

Signicado de Tipo
Denotacional tipo um conjunto de valores Construtivo tipo pode ser um tipo bsico ou um tipo composto Baseado em abstrao tipo uma interface para um conjunto de operaes

Denotacional
Conjunto de valores: domnio => tipos Signicado de uma expresso: valor de um domnio - dene o tipo da expresso Tudo possui tipo Representao atravs de operaes sobre conjuntos

Classicao de Tipos
Classicao varia de linguagem para linguagem Classicao mais usual: caracteres binrios inteiros reais

Tipos Numricos
Diferentes comprimentos (C, Fortran) C# e Java: tipos numricos com preciso denida Com ou sem sinal (C, C++, C#) Nmero complexo (Fortran, C99, biblioteca) Nmero racionais (Scheme e Lisp) Linguagem scripts: inteiros com preciso arbitrria

Tipos Decimais
Representao BCD Auxiliam no arredondamento de operaes Cobol, PL/I Arquitetura CISC: BCD nativo IEEE 754 (ponto utuante): decimais com ponto utuante de at 128 bits Motivao: comrcio on-line

Tipos Discretos
Binrios (booleanos) Inteiros Caracters Possuem: antecessor e sucessor

Enumeraes
Conjunto de nomes Normalmente ordenados Equivalente a denir constantes Em C: equivalente Em Pascal: tipo prprio

Sequncia
Tipo cujos valores denem uma sequncia de valores de um tipo Pascal: type test_score = 0..100; Pascal: tipo derivado (no inteiro)

Tipos Compostos
Records ou Structures Varitant Records ou Union Array Sets Lists Files

Ortogonalidade

Ortogonalidade -> todo statement expresso Tipo que representa ausncia de retorno Void

Vericao de Tipo
Linguagens estaticamente tipadas: denio do tipo de todos objetos A seguir: Equivalncia de tipo Compatibilidade de tipo Inferncia de tipo

Equivalncia de Tipo
Estrutural: dois tipos so iguais se possuem os mesmos componentes Algol, Modula-3, C (), ML de Nome: cada denio introduz um novo tipo Java, C#, Pascal

Exemplo
type R2 = record a, b : integer; end; type R3 = record a: integer; b : integer; end; type R4 = record b: integer; a : integer; end;

type str = array [1..10] of char

type str = array [0..9] of char

Equivalncia Estrutural
Denio do tipo expandida at: ser uma string contendo apenas nomes de campos e tipos padres Se duas strings forem iguais: mesmo tipo Baixo nvel

Exemplo
type student = record name, address: string age : integer type school = record name, address: string age: integer x : student; y : school; ... x := y;

Variaes de Equivalncia por Nome


TYPE new_type = old_type;

new_type -> alias Mesmo tipo ou tipos diferentes?

Variaes de Equivalncia por Nome


TYPE stack_element = INTEGER; MODULE stack; IMPORT stack_element; EXPORT push, pop; ... PROCEDURE push(elem : stack_element); ... PROCEDURE pop() : stack_element;

alias precisam ser do mesmo tipo!

Variaes de Equivalncia por Nome


TYPE celsius_temp = REAL; fahrenheit_temp = REAL; VAR c : celsius_temp; f : fahrenheit_temp; ... f := c;

alias deveriam representar tipos diferentes.

Variaes de Equivalncia por Nome


Equivalncia estrita por nome: alias so tipos distintos Equivalncia relaxada por nome alias so o mesmo tipo Ada: duas formas subtipo ou derivado

Exemplo

subtype stack_element is integer; ... type celsius_temp is new integer; type fahrenheit_temp is new integer;

Converso de Tipos e Casts


a := expression ou a+b dois lados precisam ter o mesmo tipo Se os tipos precisam ser exatamente os mesmos converso explcita: type cast

Converso de Tipos e Casts


Converso pode ou no ser feita durante execuo do programa: Equivalncia por nome de tipos com mesma estrutura: compilao Tipos representam mesmo conjunto de valores mas com limites distintos: execuo Tipos compostos de tipos bsicos que podem ser convertidos: execuo

Exemplo
n : integer; r : real; t : test_score; c : celsius_temp; ... t := test_score(n); n := integer(t); r := real(n); n := integer(c); c := celsiur_temp(n); ---------32 bits preciso dupla como no exemplo como no exemplo run-time check sem check converso run-time sem check sem check

Type Casts Sem Converso


Re-interpretao dos bits No muda o valor da memria Exemplo: alocao de memria C++: reinterpret_cast<tipo>

Compatibilidade
Equivalncia nem sempre necessria Compatibilidade entre tipos, Exemplo: a+b a e b tem que ser de tipos compatveis com tipos que permitem soma Regras mudam de linguagem para linguagem

Coero

Mudana implcita do tipo de uma varivel Similar a converso: pode requerer cdigo em tempo de execuo

Exemplo
type weekday = (sun, mon, ...); subtype workday is weekday range mon..fri; d : weekday; k : workday; type calendar column is new weekday; c : calendar_column; ... k := d; -- run-time check d := k; -- sem check c := d; -- erro

Coero
Confuso: tipos so misturados sem comando explcito por parte do programador Exemplo: C
short int s; unsigned long int l; char c; float f; double d; s l s f d f = = = = = = l; s; c; l; f; d;

Sobrecarga e Coero
Sobrecarga coero a + b: + soma de inteiros ou reais Sem coero: a e b tem que ser do mesmo tipo Com coero: a ou b reais: soma de nmeros reais a e b inteiros: soma de nmero inteiros Mistura: uma das variveis convertida

Referncias Universais
Referncias a qualquer tipo C/C++: void * l-value de qualquer tipo pode ser atribudo a refercia Nenhuma operao pode ser realizada sobre uma referncia universal De-referncia: como garantir tipo?

Type Tags

Tag: objeto guarda o seu tipo C++: dynamic_cast

Exemplo
import java.util.*; ... Stack my_stack = new Stack(); String s = Oi.; Foo f = new Foo(); ... myStack.push(s); myStack.pop(f); ... s = (String) myStack.pop();

Erro durante execuo caso topo da pilha no seja do tipo string

Inferncia de Tipos

Como determinar o tipo de uma expresso? Para operaes aritmticas e lgicas: fcil Para sequncias e objetos compostos: no

Sequncia
type Atype = 0..20; Btype = 10..20; var a : Atype; b : Btype;

Qual o tipo do resultado de a+b? Pascal: tipo que forma a sequncia Atribuio em sequncias: vericao em tempo de execuo

Tipos Compostos
Sobrecarga de operadores a + b, a e b structs resultado pode no ser o mesmo struct Regras variam de linguagem em linguagem e de tipo composto para tipo composto

Records (Structs)

Armazenamento de dados heterogneos Normalmente: denem um tipo

Records (Structs)
type two_chars = array [1..2] of char; struct element { char name[2]; int atomic_number; double atomic_weight; _Bool metallic; } type element = record name : two_chars; atomic_number : integer; atomic_weight : real; metalic : boolean; end;

Cada parte do record: campo Acesso ao campo: . Podem ser aninhadas

Utilizao de Memria
Campos em posies adjacentes de memria Offset para cada campo armazenado pelo compilador 4 bytes / 32 bits name atomic_number atomic_weight metallic

Utilizao de Memria

Records aninhados: Modelo por valor: cpia do record aninhado Modelo por referncia: cpia da referncia

Exemplo
Pascal
type T = record j : integer; end; S = record i : integer; n : T; end; var s1, s2 : S; ... s1.n.j := 0; s2 := s1; s2.n.j := 7; writeln(s1.n.j); (* 0 *)

Java
class T { public int j; } class S { public int i; public T n; } ... S s1 = new S(); s1.n = new T(); S s2 = s1; s2.n.j = 7; System.out.println(s1.n.j); // 7

Packed Record
Compilador procura otimizar o espao Faz com que o tempo de acesso aumente 4 bytes / 32 bits name _number atomic_weight metallic atomic_

Atribuio e Comparao
Atribuio em uma nica operao Poucas linguagens: comparao Cpia e comparao: record pequeno: campo a campo record grande: biblioteca Problema: espaos vazios no record

Minimizando Espaos Vazios


Ordenamento dos arranjos por tamanho dos campos Feito pelo compilador 4 bytes / 32 bits name metallic atomic_number atomic_weight

with Statement
ruby.chemical_composition.elements[1].name := Al; ruby.chemical_composition.elements[1].atomic_number := 13; ruby.chemical_composition.atomic_weight := 26.98154; ruby.chemical_composition.elements[1].metallic := true;

with ruby.chemical_composition.elements[1] do begin name := Al; atomic_number := 13; atomic_weight := 26.98154; metallic := true; end;

Variant Record (Union)


Duas variveis compartilhando a mesma memria Necessrio quando h restrio de memria
union { int i; double d; _Bool d; }

Tamanho da maior varivel Utilizaes: Interpretao da memria de mais de uma forma Campo mutvel de estrutura

Arrays
Tipo mais comum de dados compostos Tipo composto homogneo Semanticamente: mapeamento ndices/elemento ndice: tipo discreto: array convencional tipo no-discreto: dicionrio ou mapa

Sintaxe e Operao
Elemento: nome do array + operador [] ou () Declarao:

C Fortran Pascal Ada

char upper[26];

character, dimension (1:26) :: upper character (26) upper

var upper : array [a..z] of char

upper : array (character range a.. z) of character

Slices
Slice: pedao do array Perl, Python, Ruby e R Fortran

matrix(3:6, 4:7)

matrix(6:, 5)

matrix(:4, 2:8:2) matrix(:, (/2, 5, 9/))

Operaes
Seleo de elemento: operao mais comum: Comparao: menos comum (Ada, Fortran 90) Fortran 90: Operaes aritmticas com slices Operaes elemento a elemento

Dimenses, Limites e Alocao


Tamanho conhecido: alocao no stack Tamanho desconhecido: alocao no heap ou no stack informao do tamanho Linguagens interpretadas: dimenses e tamanho dinmico Linguagens compiladas: tamanho dinmico

Dope Vectors
Compilao: Tabela: dimenso e limites para cada array Dimenso e limites estticos: olhar tabela Dimenso e limites dinmicos: Cdigo para busca em tempo de execuo no dope vector Dope vector: limites, dimenso e tamanho do array atualizado em tempo de elaborao

Alocao no Stack
Parmetros de funo: array dinmico mais simples Pascal
function DotProduct(A, B:array [lower..upper:integer] of real):real; var i : integer; rtn : real; begin rtn := 0; for i := lower to upper do rtn := rtn + A[i]*B[i]; DotProduct := rtn end;

Chamada da funo: passagem do Dope Vector

Exemplo
void square(int n, double M[n][n]) { double T[n][n]; for (int i = 0; i < n; i++){ double s = 0; for (int k = 0; k < n; k++) { double s = j; for (int k = 0; k < n; k++) { s += M[i][k] * M[k][j]; } T[i][j] = s; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { M[i][j] = T[i][j]; } } }

Alocao no Heap
Arrays verdadeiramente dinmicos Mudam de tamanho durante a execuo Alocao no heap Linguagens: scripts, Java e C# Exemplo Java:
String s = string; ... s = s + longa;

Layout na Memria
Array unidimensional: contguo Array multidimensional: coluna ou linha til saber: otimizao do cdigo
for (i = 0; i < N; i++) { for (j = 0; j < N; j++) { ... A[i][j] ... } }

Row-Pointer Layout
Memria no-contgua Vetor de ponteiros para linhas Vantagem: linhas de tamanhos diferentes Desvantagem: mais lento (maioria das vezes)

Exemplo
char days[][10] = { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } ... days[2][3] == s; char *days[] = { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday } ... days[2][3] == s;

Clculo de Endereo
Layout contguo: como descobrir endereo de um elemento?
A : array[L1..U1] of array[L2..U2] of array[L3..U3] of elem_type; S3 = tamanho de elem_type S2 = (U3 - L3 + 1) * S3 S1 = (U2 - L2 +1) * S2 A[i,j,k]: endereo de A + (i-L1)*S1 + (j-L2)*S2 + (k-L3)*S3 Forma eficiente: (i*S1)+(j*S2)+(k*S3)+endereo de A-[(L1*S1)+(L2*S2)+(L3*S3)]

String
Vetor de caracteres Operaes limitadas Tipo prprio Mais operaes

Conjuntos
Coleo homognea no-ordenada Operaes prprias: pertence / no pertence unio / intercesso / diferena Implementao: arrays, Hash tables e rvores

Ponteiros e Tipos Recursivos


Tipo recursivo: possui referncia para ele mesmo Quase sempre: records Dados encadeados Modelo de referncia: fcil criar tipos recursivos Modelo de valor: ponteiros

Ponteiros
Varivel cujo valor uma referncia Ponteiro Endereo Pascal: apenas objetos no heap C, C++, Algol, Ada: operador endereo de

Sintaxe e Operaes
Operaes com ponteiros: alocao e de-alocao de-referncia atribuio Modelo de valor: A := B -> cpia do valor ou da referncia Modelo de referncia: A := B -> cpia da referncia

Java

Modelo intermedirio Tipos padro: modelo de valor Tipos denidos pelo usurio: modelo de referncia

Modelo de Referncia ML
datatype chr_tree = empty | node_of_char * chr_tree * chr_tree

chr_tree: vazio n de uma rvore com 2 referncias

Modelo de Referncia Lisp


(#\R (#\X () ()) (#\Y (#\Z ()()) (#\W ()())))

Modelo de referncia No estaticamente tipada

Tipos Mutuamente Recursivos


Como resolver no modelo de referncia?
datatype sym_tab_rec = variable of ... | type of ... | ... | subroutine of {code : syn : syn_tree_node, ...} and syn_tree_node = expression of ... | loop of ... | ... | subr_call of {subr : sym_tab_rec, ...};

Estaticamente tipada: Construo explcita na linguagem

Modelo de Valor
type chr_tree_ptr = ^chr_tree; chr_tree = record left, right : chr_tree_ptr; val : char; end; type chr_tree; type chr_tree_ptr is access chr_tree; type chr_tree is record left, right : chr_tree_ptr; val : character; end record;

Pascal

Ada

struct chr_tree { struct chr_tree *left, *right; char val; }

Alocao
new(my_ptr);

Pascal Ada C

my_ptr := new chr_tree;

my_ptr = malloc(sizeof(struct chr_tree));

my_ptr = new chr_tree(args);

C++, Java e C#

De-referncia
Explcita:
my_ptr^.val := X;

Pascal C

my_ptr->val = X;

Implcita:
T : chr_tree; P : chr_tree_ptr; ... T.val := X; P.val := Y;

Ada

Removendo Objetos
Alocao no Heap: remoo de objetos no utilizados Duas opes: remoo explcita
dispose(my_ptr);

Pascal C C++

free(my_ptr);

delete my_ptr;

Referncias Solta
Ponteiro que no aponta para um objeto vlido Ex.: ponteiro para varivel local
int i = 3; int *p = &i; ... void foo(){int n = 5; p = &n}; ... cout << *p; foo() ... cout << *p;

int *p = new int; *p = 3; ... cout << *p; delete p; ... cout << *p;

Coletor de Lixo
Gerenciamento de memria: Custoso para o programador Fonte de erros Coletor de lixo: Recupera memria automaticamente Como funciona?

Contagem de Referncia
Quando que um objeto na memria pode ser removido? Quando no h nenhuma referncia para ele Contagem de referncia: Objeto criado: contagem = 1 Novo ponteiro: contagem incrementada Ponteiro removido: contagem decrementada Contagem = 0 -> objeto removido

Contagem de Referncia
Implementao: Necessrio saber a localizao de cada ponteiro Descritores de tipo: Tabela com tipos e onde ponteiros podem ser encontrados dentro de cada tipo Problema: Objetos sem referncia -> inteis Objetos inteis -> sem referncia ?

Tracing Collection
Objeto til: Pode ser encontrado seguindo uma sequncia de ponteiros, comeando com um objeto que est no stack Funcionamento: busca recursiva no heap

Mark-and-Sweep
Algoritmo clssico Executado quando espao no heap ca abaixo de um limiar Trs passos: Coletor passa por todos objetos do heap, marcando todos os objetos como inteis Comeando com ponteiros fora do heap, o coletor recursivamente explora os dados encadeados. Cada objeto encontrado marcado como til Coletor passa novamente por todos objetos do heap, movendo cada bloco intil para a lista de blocos livres Informao extra: incio e m de cada objeto no heap

Pointer Reversal
Explorao do mtodo anterior: usa muita memria: marcao dos dados Algoritmo alternativo: O sentido dos ponteiros da lista encadeada invertido Ponteiro do objeto apontado para o objeto que apontava Objeto atual e anterior so armazenados Na volta: ponteiros so invertidos novamente Baixo consumo de memrio

Stop-and-Copy
Reduo da fragmentao Evita a busca inicial e nal Diviso do heap em dois blocos de tamanhos iguais Quando a primeira parte est quase cheia: Busca por objetos teis Cada objeto til copiado para a segundo bloco Ponteiros para esse objeto so redirecionados para o novo bloco

Generational Collection
Objetos alocados dinmicamente tendem a ter uma vida curta Heap dividido em mltiplas partes -- normalmente duas Quando o espao no heap est acabando: Lixo coletado da parte mais nova Se espao recuperado no for suciente, busca na parte mais velha Objeto na parte nova que sobrevive uma busca: vai para parte velha

Listas
Denio recursiva Lista : lista vazia par (objeto, lista) Linguagens funcionais: muito utilizadas Linguagens imperativas: disponveis em scripts

List Comprehensions
Adaptao de notao matemtica

[i*i for i in range(1, 100) if i % 2 ==1]

{i i | i 2 {1, , 100} ^ i mod 2 = 1}

Rotinas e Abstraes de Controle

Introduo
Abstrao: associao nome com pedao (complicado) de cdigo Abstrao de controle: objetivo uma operao bem denida Principal mecanismo: rotinas (funes e procedimentos)

Rotinas
Realizam uma operao para quem a chama Chamada da rotina: transfere o uxo de controle para a rotina Maior parte das rotinas: parametrizadas argumentos alteram o seu funcionamento

Rotinas
Argumentos: parmetros verdadeiros so mapeados nos parmetros formais durante a chamada da rotina Funo: retorna valor Procedimento: no retorna valor

O que ser visto


O que acontece durante a chamada de uma rotina Expanso em linha Parmetros de rotinas Rotinas genricas Manipulao de excees

Stack
sp fp
Subrotina D
procedure C

Argumentos para rotinas Temporrios

D; E procedure B if ... then B else C

Subrotina C Variveis Locais Misc. Endereo de retorno

procedure A B -- main program A

Subrotina B Subrotina B Subrotina A

fp
(quando C est sendo executado)

sp: stack pointer, fp: frame pointer

Sequncia de Chamada
Cdigo executado quando uma rotina chamada e aps a sua execuo Prlogo e eplogo Responsabilidade: gerenciar o stack

Prlogo
Salva o endereo de retorno Muda o sp e armazenamento em registradores Alocao de espao Atualizao do fp Cdigo de inicializao de objetos

Eplogo
Retorno de parmetros Cdigo de nalizao de objetos Remoo da memria alocada Recuperao dos registradores

Sequncia Tpica
sp
Argumentos para rotinas chamadas
Quadro atual

Chamada: salva os registradores que sero utilizados aps o retorno calcula os valores dos argumentos
Quadro anterior

Temporrios Variveis Locais Registradores Salvos

fp

fp salvo Endereo de retorno Argumentos para rotinas

pula para a rotina passando o endereo de retorno

Sequncia Tpica
sp
Argumentos para rotinas chamadas
Quadro atual

Prlogo: aloca memria para o quadro salva o antigo fp no stack e atribui um novo valor para ele salva os registradores que sero sobrescritos

Temporrios Variveis Locais Registradores Salvos

fp

fp salvo
Quadro anterior

Endereo de retorno Argumentos para rotinas

Sequncia Tpica
sp
Argumentos para rotinas chamadas Temporrios Variveis Locais Registradores Salvos
Quadro atual

Eplogo: move os valores de retorno para o local adequado recupera registradores salvos recupera fp e sp
Quadro anterior

fp

fp salvo Endereo de retorno Argumentos para rotinas

pula para o endereo de retorno

Expanso Em linha
Na chamada: cpia do cdigo da rotina No ocorre a sequncia de chamada Permite otimizaes do compilador Exemplo (C++ e C99):
inline int max(int a, int b) {return a > b ? a : b;}

Sugesto para o compilador Problemas: tamanho do cdigo e recurso

Passagem de Parmetros
Parmetros: alteram o comportamento da rotina fornecem dados Parmetros na declarao: parmetros formais Argumentos passados: parmetros reais A seguir: formas de passagem de parmetros

Modos de Passagens de Parmetros


Rotina p e parmetro x p(x); Duas implementaes alternativas: copiar o valor de x fornecer o endereo de x Modos: passagem por valor passagem por referncia

Exemplo
x : integer -- global procedure foo(y : integer) y := 3 print x ... x := 2 foo(x) print x

Passagem por Valor / Retorno


Passagem por referncia: modicar a varivel Mesmo comportamento: chamada por valor/retorno Valor copiado na entrada da funo E copiado de volta no retorno da funo

Exemplo
x : integer -- global procedure foo(y : integer) y := 3 print x ... x := 2 foo(x) print x

C
Apenas: passagem por valor Emulando passagem por referncia: passagem direta do endereo (ponteiros) Exemplo:
void swap(int *a, int *b) { int t = *a; *a = *b; *b = t; } ... int v1, v2; ... swap(&v1, &v2);

Passagem por Compartilhamento


Linguagens com modelo por referncia Nem por valor, nem por referncia S existem referncias Cpia de referncia = referncia ! Passagem por compartilhamento: Cpia da referncia Altera o valor, mas no a identidade

Java
Passagem por valor: tipos padro Passagem por compartilhamento: tipos denidos pelo usurio Consequncia: tipos padres no podem ser alterados durante rotina

Valor x Referncia
Passagem por valor: assegura que o valor no modicado Passagem por referncia: permite modicao do argumento menor custo computacional leva a bugs -> confuso semntica

Parmetros Apenas de Leitura


Combinao: ecincia computacional de passagem por referncia segurana de passagem por valor Parmetro apenas de leitura: s pode aparecer do lado direito de expresses

Exemplo C

void append_to_log(const huge_record *r) {... ... append_to_log(&my_log);

O const vale para o valor apontado por r

Exemplo: Ada
Trs modos de passagem de parmetros: in: apenas de leitura out: apenas de escrita in out: escrita e leitura

Referncias em C++
Passagem por referncia:
void swap(int &a, int &b){int t = a; a = b; b = t;}

Podem ser apenas de leitura: const Implementao: passagem do endereo no podem ser de-referenciados!

Retornando Referncias
til para operadores
cout << a << b << c;

=
((cout.operator<<(a)).operator<<(b)).operator<<(c);

Sem retorno de referncia:


*(*(cout << a) << b) << c;

Fechamentos como Parmetros


Fechamentos: rotina + contexto Podem ser passados como parmetros

Exemplo
procedure apply_to_A(function f(n : integer) : integer; var A : array[low..high:integer] of integer); var i : integer; begin for i := low to high do A[i] := f(A[i]); end; ... var k : integer (* escopo aninhado *) ... function add_k(m : integer) : integer; begin add_k := m + k; end; ... k := 3; apply_to_A(add_k, my_array);

Resumo
Modo valor in, const out value/result var, ref
copartilhamento

Linguagens C/C++, Pascal, Java/C# Ada, C/C++, Modula-3 Ada AlgolW Fortran, Pascal, C++ Lisp/Scheme, ML, Java/C# Ada

Implementao

Operaes leitura, escrita leitura escrita leitura, escrita leitura, escrita leitura, escrita leitura, escrita

Muda real? no no sim sim sim sim sim

Alias? no talvez talvez no sim sim talvez

valor valor ou referncia valor ou referncia valor referncia valor ou referncia valor ou referncia

in out

Passagem de Arrays

Tempo de unio da dimenso e limites Execuo: aberto ou conformant

Parmetros Default
Parmetro opcional Se o parmetro estiver faltando: valor padro utilizado Exemplo (Ada):
type filed is integer range 1..integerlast; type number_base is integer range 2..16; default_width : field := integerwidth; default_base : number_base := 10; procedure put(item : in integer; width : in field := default_width; base : in number_base := default_base);

Parmetros Nomeados
At agora: parmetros posicionais 1o parmetro real = 1o parmetro formal Alternativa: parmetros nomeados Chamada da funo com o nome formal do parmetro explcito

Parmetros Nomeados
put(item => 37, base => 8);

put(base => 8, item => 37);

put(37, base => 8);

Exemplo
Parmetros nomeados como documentao
format_page(columns => 2, window_height => 400, window_width => 200, header_font => Helvetica, body_font => Times, title_font => Times_Bold, header_point_size => 10, body_point_size => 11, title_point_size => 13, justification => true, hyphenation => false, page_num => 3, paragraph_indent => 18, background_color => white);

Nmero Varivel de Argumentos


Nmero de argumentos indeterminado Exemplo: printf e scanf Recurso pouco comum: C/C++, Python, Lisp

Exemplo
#include <stdarg.h> /* definio de va_list, va_start, ... */ int printf(char *format, ...) { va_list args; va_start(args, format); ... char c = va_arg(args, char); ... double d = va_arg(args, double); ... va_end(args); }

Exemplo
Java/C#: parmetros ocultos do mesmo tipo
static void print_lines(String foo, String... lines) { System.out.println(First argument is \+ foo \.); System.out.println(There are + lines.length+additional arguments:); for (String str: lines){ System.out.println(str); } } ... print_lines(Hello, World., Depois , dos trs pontos);

First argument is Hello, World. There are 2 additional arguments: Depois dos trs pontos

Retorno de Funes
Como denotar o retorno da funo Sintaxe varia de linguagem para linguagem Pascal, Fortran: atribuio a uma varivel com nome igual ao da funo Soluo mais moderna: return

Exemplo
Matlab: retorno nomeado e mltiplo

function [A, B, C] = foo() A = 1; B = 2; C = 3;

Mdulos e Rotinas Genricas


Parmetros: Mudana do comportamento Dados Operaes: podem no depender do tipo Exemplo: operaes sobre la

Mdulos e Rotinas Genricas


Polimorsmo paramtrico explcito: Rotinas genricas Conjunto de rotinas similares: especializao do tipo Ada, C++, Java, C#

Containers
Estrutura de dado Armazenam outros dados Exemplo: stack, queue, conjuntos, dicicionrios Tipo: genrico Ada e C++

Exemplo
C++
template <class item, int max_items = 100> class queue { item items[max_items]; int next_free; int next_full; public: queue(){ next_free = next_full = 0;} void enqueue(item it) { items[next_free] = it; next_free = (next_free + 1) % max_items; } item dequeue() { item rtn = items[next_full]; next_full = (next_full + 1) % max_items; return rtn; } };

queue<int, 50> int_queue; queue<float> float_queue;

Parmetros Genricos

Quais parmetros podem ser genricos? Ada e C++: tipos comuns, rotinas e classes Java e C#: apenas tipos comuns

Implementao
Compilador: cpia em cada implementao Se possvel: cdigo compartilhado Java: sempre compartilha cdigo Ada e C++: similar a macro Vericao de tipo Inserido no contexto da linguagem

Limitaes de Parmetros Genricos


Interface de uma funo genrica: informaes de como utiliz-la Ada, Java e C#: operaes permitidas sobre parmetro genrico devem ser explicitadas

Exemplo
Ada
generic type T is private; with function <(x, y : T) return Boolean; function min(x, y : T) return T is begin if x < y then return x; else return y; end if; end min; function string_min is new min(string, <); function date_min is new min(date, date precedes);

Exemplo
Java
public static <T extends Comparable<T>> void sort(T A[]) { ... if (A[i].compareTo(A[j]) >= 0) ... ... } ... Integer[] myArray = new Integer[50]; ... sort(myArray);

Exemplo
C#
static void sort<T>(T[] A) where T : IComparable { ... if (A[i].CompareTo(A[j]) >= 0) ... ... } ... int[] myArray = new int[50]; sort(myArray);

Exemplo
C++

template<class T> void sort(T A[], int A_size) { ...

Instanciao
Ada: instanciao explcita
procedure int_sort is new sort(integer, int_array, <);

C++: instanciao implcita


int ints[10]; double reals[50]; string strings[30]; sort(ints, 10); sort(reals, 50); sort(strings, 30);

Excees
Erro na execuo de uma rotina Como sinalizar o problema? Inventar um valor que sinaliza o problema Retornar um status para quem chama a rotina Receber uma funo que lida com possveis erros Exceo: soluo apropriada

Excees
Permitem: denio do uxo normal do cdigo caso tenha problema, uxo redirecionado Parte do cdigo que lida com o erro: Nome: manipulador (handler) assume o controle da rotina assim que o erro acontece

Exemplo
try { ... if (algo_inesperado) throw erro(); ... cout << tudo ok << endl; ... } catch (erro) { cout << problema! << endl; }

Exemplo
try { ... foo(); ... cout << tudo ok << endl; ... } catch (erro) { cout << problema! << endl; }

foo() { ... if (algo_inesperado) throw erro(); ... }

Handlers
Trs possveis tarefas: corrigir o erro, de forma que o programa possa continuar operando Erro out of memory -> alocar mais memria se o erro no pode ser corrigido localmente: limpar lixo e fornecer exceo novamente se nada puder ser feito: exibir mensagem de erro na tela

Denindo Excees
Linguagem : Erros semnticos dinmicos Programador: Pode denir excees especcas Excees pr-denidas: overow, end-of-le, out-of-range, diviso por zero

Exemplo
Ada: exceo um tipo padro
declare empty_queue : exception;

Linguagens OO: classes


class duplicate_in_set { item dup; }; ... throw duplicate_in_set(d);

Propagao de Excees
try { // Tenta ler do arquivo ... // Cdigo complicado de leitura ... } catch(end_of_file) { ... } catch(io_error e) { ... } catch(...) { ... }

Operaes de Limpeza
Cdigo que executado sempre caso a sada seja normal ou com exceo Modula-3, Python, Java e C#
TRY myStream := OpenRead(myFileName); FINALLY Close(myStream); END;

Emulando Excees
Forma mais comum: goto C: rotinas da biblioteca padro setjmp: salva num buffer o estado atual do programa retorno: normal = 0, de um longjmp 0 longjmp: restaura o estado do programa a partir de um buffer

Exemplo

if (!setjmp(buffer)) { /* cdigo protegido */ } else { /* handler */ }

Abstrao de Dados e Orientao a Objetos

Introduo
Mdulos: coleo de rotinas e variveis estticas encapsulamento e ocultao de informao Mdulos como tipos: mdulos que podem ter vrias cpias Classes: mdulo como tipos + herana

Exemplo: Mdulo
CONST stack_size = ... TYPE element = ... ... MODULE stack_manager; IMPORT element, stack_size; EXPORT stack, init_stack, push, pop; TYPE stack_index = [1..stack_size]; stack = RECORD s : ARRAY stack_index OF element; top : stack_index; END; PROCEDURE init_stack(VAR stk : stack); BEGIN stk.top := 1; END init_stack; PROCEDURE push (VAR stk : stack, elem : element); BEGIN IF stk.top = stack_size THEN error; ELSE stk.s[stk.top] := elem; stk.top := stk.top + 1; END; END push; VAR A, B : stack; var x, y : element; ... init_stack(A); init_stack(B); ... push(A, x); ... y := pop(B); PROCEDURE pop (VAR stk : stack) : element; BEGIN IF stk.top = stack_size THEN error; ELSE stk.top := stk.top - 1; RETURN stk.s[stk.top]; END; END pop; END stack_manager;

Exemplo: Mdulo como Tipo


const stack_size = ... type element = ... ... type stack = module imports (element, stack_size) exports (push, pop) type stack_index = 1..stack_size; var s : array stack_index of element top : stack_index procedure push(elem : element) = ... function pop returns element = ... ... initially top := 1 end stack

VAR A, B : stack; var x, y : element; ... A.push(x) ... y := B.pop

Introduo
Mdulo: gerentes Mdulo exporta um tipo abstrato Mdulo inicializado e nalizado Mdulo como tipo e classes: O prprio mdulo a abstrao Instncia do mdulo criada e nalizada

Introduo
Classe: Herana: novas abstraes criadas a partir de abstraes que j existem unio dinmica de mtodos: nova abstrao pode ser usada em contextos que esperavam a abstrao antiga Instncia da classe = objeto

Introduo
Encapsulamento, herana e unio dinmica: Simula (60s) Melhorias sobre encapsulamento: Clu, Modula, Euclid (70s) Melhorias sobre herana e unio dinmica: Smalltalk (70s)

Introduo
Linguagens OO modernas: Eiffel, C++, Modula-3, Ada 95, Fortran 2003, Python, Ruby, Java e C# Objective-C: Mensagens de Smalltalk + C

O que ser visto:


Encapsulamento e ocultao de informao Inicializao e nalizao Unio dinmica de mtodos Herana mltipla Linguagens verdadeiramente orientada a objetos

Programao OO
Evoluo dos programas: necessidade de ocultao de informao abstrao de dados Benefcios: Reduz conceitos que o programados tem que aprender Contingncia de erros Aumenta independncia entre partes do programa

Programao OO
Na prtica: re-uso do cdigo complicado Classe precisa ser levemente modicada Ex.: FIFO para deque Herana: permite estender classes j criadas ou renar

Exemplo
class list_err { // exceo public: char *description; list_err(char *s){description = s;} }; class list_node { list_node* prev; list_node* next; list_node* head_node; public: int val; class list_node() { prev = next = head_node = this; val = 0; } list_node* predecessor() { if (prev == this || prev == head_node) return 0; return prev; } list_node* successor() { if (next == this || next == head_node) return 0; return next; } bool singleton() { return (prev == this); } void insert_before(list_node* new_node) { if(!new_node->singleton()) throw new list_err(insero repetida); prev->next = new_node; new_node->prev = prev; new_node->next = this; prev = new_node; new_node->head_node = head_node; } void remove(){ if(singleton()) throw new list_err(n no existe); prev->next = next; next->prev = prev; prev = next = head_node = this; } ~list_node() { if(!singleton()) throw new list_err(n ainda na lista); } };

Nomenclatura
Variveis membros da classe: Atributos ou campos prev, next, head_node, val Rotinas membros da classe: Mtodos predecessor, successor, insert_before e remove this: ponteiro para instncia que est executando o cdigo

Exemplo
class list{ list_node header; public: int empty() { return header.singleton(); } list_node* head() { return header.successor(); } void append(list_node *new_node) { header.insert_before(new_node); } ~list() { if (!header.singleton()) throw new list_err(Lista no vazia) } };

Exemplo
Como criar listas:

Stack
list my_list_ptr; list_node elem;

Heap
list* my_list_ptr = new list; list_node* elem_ptr = new list_node;

Criao: execuo do construtor mtodo com mesmo nome que a classe Destruo: execuo do destrutor mtodo com nome da classe com ~ na frente

Exemplo
class list_err { // exceo public: char *description; list_err(char *s){description = s;} }; class list_node { list_node* prev; list_node* next; list_node* head_node; public: int val; list node() { prev = next = head_node = this; val = 0; } list_node* predecessor() { if (prev == this || prev == head_node) return 0; return prev; } list_node* successor() { if (next == this || next == head_node) reuturn 0; return next; } bool singleton() { return (prev == this); } void insert_before(list_node* new_node) { if(!new_node->singleton()) throw new list_err(insero repetida); prev->next = new_node; new_node->prev = prev; new_node->next = this; prev = new_node; new_node->head_node = head_node; } void remove(){ if(singleton()) throw new list_err(n no existe); prev->next = next; next->prev = prev; prev = next = head_node = this; } ~list_node() { if(!singleton()) throw new list_err(n ainda na lista); } };

Membros Pblicos e Privados


public: Tudo que vem depois: visvel de fora da classe Determina quais membros sero visveis para quem usa a classe (interface) private: Membros visveis apenas para a classe Oculta informao de quem usa a classe

Declarao
list_node.h
class list_node { list node* prev; list node* next; list_node* head_node; public: int val; list_node(); list_node* predecessor(); list_node* successor(); bool singleton(); void insert_before(list_node* new_node); void remove(); ~list_node(); };

list_node.cpp
... void list_node::inset_before(list_node* new_node) { ... } ...

Rotinas Curtas
Programas OO: chamadas para rotinas pequenas informao escondida por trs de uma chamada Boa prtica: atributos sempre privados mtodos: get e set para modic-los

Propriedades
Propriedades: membros com mtodos set e get prprios Accessors: mtodos que atributem e lem valores de atributos Python e C#

Exemplo
class list_node { ... int val; // val privado public int Val { get { return Val; } set { val = value; // value palavra chave } } ... }

list_node n; ... int a = n.Val; // chama o mtodo get n.Val = 3; // chama o mtodo set

Classes Derivadas
J temos a lista Queremos uma la Soluo OO: la derivada a partir da lista la (lha ou derivada) de lista lista (me, base, superclasse) de lha Classe derivada tem todos os membros da classe base

Exemplo
class queue : public list { public: void enqueue(list_node* new_node){ append(new_node); } list_node* dequeue(){ if(empty()) throw new list_err(fila vazia); list_node* p = head(); p->remove(); return p; } };

Classe Base de Propsito Geral


list_node: valor armazenado tem que ser inteiro Como fazer uma classe base mais geral?

Exemplo: Ada 95
class gp_list_node { gp_list_node* prev; gp_list_node* next; gp_list_node* head_node; public: gp_list_node(); gp_list_node* predecessor(); gp_list_node* successor(); bool singleton(); void insert_before(gp_list_node* new_node); void remove(); ~gp_list_node(); };

class int_list_node : public_list_node { public: int val; int_list_node(){ val = 0; } int_list_node(int v) { val = v; } };

Sobrecarga de Construtor
No exemplo: construtor foi sobrecarregado Pode no receber nenhum argumento: val inicializado como vazio Pode receber inteiro: val inicializado com inteiro fornecido
int_list_node element1; // val = 0 int_list_node element2(1); // val = 1 int_list_node *e_ptr = new int_list_node(13); // val = 13

Modicando Mtodos da Classe Base


Classe derivada pode modicar mtodos da classe base Exemplo:
class int_list_node : public list_node { public: ... void remove() { if (!singleton()) { prev->next = next; next->prev = prev; prev = next = head_node = this; } } };

Exemplo

class int_list_node : public_list_node { public: ... void remove() { try{ gp_list_node::remove(); } catch(list_err) { // no faz nada } };

Acessando Membros da Classe Base

gp_list_node::remove(); // C++ super.remove(); // Java base.remove(); // C# super remove. // Smalltalk [super remove] // Objective C

Containers/Collections
Abstrao que contm coleo de objetos Conjuntos, queues, stacks, dicionrios Vrias formas de denir containers: Exemplos: objetos so derivados do tipo base Outras solues: ns possuem ponteiros para objetos armazenados lista derivada da classe do objeto derivado

Encapsulamento e Herana

Mecanismos de encapsulamento: agrupamento de dados e sub-rotinas classe como gerente

Encapsulamento em Mdulos
Ocultao da dados Mdulo: import e export Tipos opacos: Mdulo exporta o tipo T Resto do programa: s pode passar objetos deste tipo para rotinas denidas no mdulo

Encapsulamento em Mdulos
Diviso: cabealho e implementao Permite compilao separada Modula-2: tudo no cabealho pblico tudo na implementao privado

Encapsulamento em Mdulos
Ada: cabealho dividido em parte pblica e privada

package foo is -- header ... type T is private; ... private ... type T is ... ... end foo;

Tipo T: opaco

Parmetro this
Como o mdulo sabe qual a instncia que est executando? Soluo inocente: cpia das rotinas em cada instncia Soluo prtica: uma nica verso de cada rotina parmetro extra oculto: instncia

Exemplo

my_stack.push(x);

push(my_stack, x);

Falta de Cabealhos em Java e C#


C# e Java: no possuem arquivos de cabealho Parte pblica: denida no cdigo fonte Compilador: extrai informao a partir do cdigo

Encapsulamento com Herana


Classe B deriva de A Membros privados de A so visveis em B? Membros pblicos de A continuam pblicos em B?

Exemplo
Queue: mtodo append da classe list no faz sentido
class queue : private list { public: using list::empty; using list::head; void enqueue(gp_list_node* new_node); gp_list_node* dequeue(); };

Herana: privada tudo herdado privado

C++: Protected
Qualicador de visibilidade como public e private O que faz: Membros protected so visveis em mtodos da prpria classe mtodos de classes derivadas

Regras de Visibilidade: C++


Classe pode limitar a visibilidade de seus membros membros pblicos: visveis quando a classe est no escopo membros privados: visveis apenas nos mtodos membros protegidos: privados + classe derivada

Regras de Visibilidade: C++


Classes derivadas podem restringir a visibilidade de membros da classe base, nunca ampliar Membros privados da classe base: so visveis apenas na classe base Membros pblicos/protegidos da classe base pblica: mantm a visibilidade Membros pblicos/protegidos da classe base protegida: se tornam protegidos Membros pblicos/protegidos da classe base privada: se tornam privados

Regras de Visibilidade: C++

Classe derivada que limita a visibilidade de membros de classe base protegida/privada pode restaurar visibilidade de membros especcos

Visibilidade em Outras Linguagens


Java e C#: parecido com C++ no existe classe base privada, pblica ou protegida Classes derivadas no podem nem restringir nem ampliar visibilidade protected em Java: limita visibilidade para classes derivadas dentro do mesmo package Smalltalk e Objective-C: sem visibilidade, tentativa de executar cdigo em tempo de execuo Python: todos membros so pblicos

Aninhamento de Classes
Denio de uma classe dentro da outra Se inner denida dentro de outer inner enxerga os membros privados de outer? Caso sim, de qual instncia? C++ e C#: s membros estticos so visveis Java: todos os membros so visveis Cada instncia de inner pertence a uma instncia de outer

Exemplo
class Outer { int n; class Inner { public void bar() {n = 1}; } Inner i; Outer() {i = New Inner();} public void foo() { n = 0; System.out.println(n); // 0 i.bar(); System.out.println(n); // 1 } }

Extenso de Tipos
Smalltalk, Objective-C, C++, Java e C#: linguagens projetadas OO mdulo como tipo: classe fornece encapsulamento e herana Ada, Fortran 93, Modula-3: extenses OO de linguagens existentes mdulos: encapsulamento herana: extenso de estruturas

Exemplo: Ada 95
package gp_list is list_err : exception; type gp_list_node is tagged private; type gp_list_node_ptr is access all gp_list_node; procedure initialize(self : access gp_list_node); function predecessor(self : access gp_list_node) return gp_list_node_ptr; function successor(self : access gp_list_node) return gp_list_node_ptr; function singleton(self : access gp_list_node) return boolean; procedure insert_before(self : access gp_list_node; new_node : access gp_list_node_ptr); procedure remove(self : access gp_list_node); type list is tagged private; type list_ptr is access all list; procedure initialize(self : access list); procedure finalize(self : acess list); function empty(self : access list) return boolean; function head(self : access list) return gp_list_node_ptr; procedure append(self : access list; new_node : gp_list_node_ptr); private type gp_list_node is tagged record prev, next, head_node : gp_list_node_ptr; end record; type list is tagged record header : aliased gp_list_node; end record; end gp_list; ... package body gp_list is -- definio das rotinas end gp_list;

package gp_list.queue is -- queue filha de gp_list type queue is new list with private procedure initialize(self : access queue); procedure finalize(self : access queue); procedure enqueue(self : access queue; new_node : gp_list_node_ptr); function dequeue(self : access queue) return gp_list_node_ptr; private type queue is new list with null record; -- sem campos novos ... package body gp_list.queue is procedure initialize(self : access queue) is begin initialize(list_ptr(self)); end initialize; procedure finalize(self : access queue) is begin finalize(list_ptr(self)); end enqueue; function dequeue(self : access queue) return gp_list_node_ptr is rtn : gp_list_node_ptr; begin if empty(list_ptr(self)) then raise list_err; end if; rtn := head(list_ptr(self)); remove(rtn); return rtn; end dequeue; end gp_list.queue;

Exemplo
Package child em Ada 95: parecido com classe derivada mas gerencia um tipo Abordagens similar: classes em Python

Extenso sem Herana


O que fazer quando herana no possvel? Cdigo j existente: no permite herana C#: extension methods
static class AddToString { public static int toInt(this string s) { return int.Parse(s); } } int n = mySring.toInt();

Inicializao e Finalizao
Linguagens OO: inicializam e nalizam objetos Inicializao: mtodo construtor Finalizao: mtodo destrutor

Inicializao e Finalizao
Escolhendo um construtor: Uma classe pode ter 0 ou mais construtores Modelo por referncia: Criao explcita de objetos: fcil saber quando construtor executado Modelo por valor: Criao implcita: objeto criado sem inicializao OU mecanismo para escolher construtor

Inicializao e Finalizao
Ordem de execuo: Classe A deriva de Classe B: construtor de B precisa ser chamado antes do construtor de A? Se Classe A tem um atributo da Classe B: construtor de B precisa ser chamado antes do construtor de A? C++: sim e sim

Inicializao e Finalizao
Destrutores: teis em linguagens que no tem coleta automtica de lixo Facilitam a recuperao de memria alocada

Escolhendo um Construtor
Smalltalk, Eiffel, C++, Java e C#: mais de um construtor por classe C++, Java e C#: Todos com o mesmo nome Diferem no nmero e tipo dos argumentos Smalltalk e Eiffel: Construtores com nomes diferentes Cdigo deve explicitar o construtor a ser utilizado

Exemplo: Eiffel
class COMPLEX creation -- define os construtores new_cartesian, new_polar feature {ANY} -- pblico x, y : REAL new_cartesian(x_val, y_val : REAL) is do x := x_val; y := y_val end new_polar(rho, theta : REAL) is do x := rho * cos(theta) y := rho * sin(theta) end feature {NONE} -- privado end ... a, b : COMPLEX !!b.new_cartesian(0, 1) !!a.new_polar(pi/2, 1)

Referncias e Valores
Smalltalk, Python, Ruby e Java: variveis referenciam objetos C++, Ada 95: variveis so objetos C#: class: referncia struct: valor

Construtores em C++

foo b; // chama foo::foo() foo b(10, x); // chama foo::foo(int, char)

Construtores de Cpia
foo bar ... foo foo a; // chama foo::foo() b; // chama bar::bar() c = a; // chama foo::foo(foo &) d = b; // chama foo::foo(bar &)

foo bar ... c = d = a, c, d; // chama foo::foo() trs vezes b; // chama bar::bar() a; b; // chama foo::operator=(foo &) // chama foo::operator=(bar &)

Inicializao e Atribuio
C++: distino entre atribuio e inicializao Desempenho:
foo a = b + c; foo t; t = b.operator+(c); foo a = t;

Chamadas: foo::foo() foo::foo(foo &) foo::~foo()

Exemplo: Eiffel

Todas as variveis so inicializadas com um valor default Inclusive atributos de classes

Ordem de Construo
C++: todo objeto deve ser inicializado Se A deriva de B: B->A Como passar parmetros para construtor de B?

class foo : public bar { foo( foo param ) : bar( bar_param ); ...

Construo de Atributos
C++: permite escolha dos valores iniciais dos atributos
list_node() : prev(this), next(this), head_node(this), val(0) {};

Exemplo: C++
class foo : bar { mem1_t member1; // atributo cujo tipo classe mem1_t mem2_t member2; // atributo cujo tipo classe mem1_t } foo::foo( foo_params ) : bar( bar_args ), member1 ( mem1_args), member2 (mem2_args) { ... }

Uso do construtor de cpia para: member1 e member2

Exemplo: Java
Java: requer inicializao (como C++) Sintaxe diferente Primeira linha do construtor:
super( args );

Caso no tenha chamada explcita: compilador insere uma chamada para: super()

Exemplo: Java

Modelo de referncia: atributos que so classes: inicializao para null Inicializao explcita no construtor

Destrutor
Chamado na ordem inversa do construtor
class name_list_node : public gp_list_node { char *name; public: name_list_node() { name = 0; } name_list_node(char *n) { name = new char[strlen(n)+1]; strcpy(name, n); } ~name_list_node(){ if (name != 0) { delete [] name; } } }

Unio Dinmica de Mtodos


Classe D deriva de Classe C D pode ter todos os membros pblicos de C Tudo que pode ser feito com C... ... pode ser feito com D Polimorsmo de subtipo

Unio Dinmica de Mtodos

class person { ... class student : public person { ... class professor : public person { ... student s; professor p; ... person *x = &s; person *y = &p;

class person { ... public: void print_data(); ... } class student : public person { ... public: void print_data(); ... } class professor : public person { ... public: void print_data(); ... } student s; professor p; ... person *x = &s; person *y = &p; ... s.print_data(); // student::print_data p.print_data(); // professor::print_data ... x->print_data(); // ?? y->print_data(); // ??

Unio Dinmica de Mtodos


Unio esttica de mtodos: person::print_data() Unio dinmica de mtodos: student::print_data() professor::print_data()

Consistncia
Unio dinmica de mtodos: classe garante consistncia
class text_file { char *name; long position; public: void seek(long where); ... }; class read_ahead_text_file : public text_file { char *upcoming_characters; public: void seek(long where); //redefinio ... };

Se read_ahead_text_le::seek no for executado: upcoming_les poder car insistente

Unio Dinmica de Mtodos


Unio dinmica para todos os mtodos: Smalltalk, Objective-C, Python e Ruby Unio dinmica padro, mas pode ser alterado Java e Eiffel Unio esttica padro/ Unio dinmica opcional Simula, C++, C# e Ada

Unio Dinmica Opcional


Unio esttica Mtodo redenido Unio dinmica Mtodo sobrecarregado

Mtodos Virtuais
C++ e C#: mtodos virtuais usam unio dinmica Chamadas para mtodos virtuais: so encaminhadas para a implementao adequada em tempo de execuo
class person { public: virtual void print_data(); ... }

Classe Abstrata
Classe base: Mtodo sem implementao S possui interface C++: mtodo virtual puro Classe base: abstrata No podem ter objetos

Exemplo
C++
class person { ... virtual void print_data() = 0; ...

C#
abstract class person { ... public abstract void print_data(); ...

Encontrando Mtodos
Como os mtodos dinmicos so encontrados em tempo de execuo? Objeto referenciado deve conter a informao necessria para que o mtodo correto seja encontrado Implementao usual: vtable

Busca por Mtodos


class foo { int a; double b; char c; public: virtual void virtual void virtual void virtual void ... }; foo F;

F
k l m n (... (... (... (...

vtable de foo
k l m n
Implementao de m

a b c

Busca por Mtodos


B
a b c w

class bar : public foo { int w; public: void m(); virtual double s (... virtual char *t (... ... }; bar B;

vtable de bar
k l m n s t
bar::m foo::n bar::s

Exemplo

foo F; bar B; foo *q; bar *s; ... q = &B; // Ok s = &F; // Erro ... // Verificao em tempo de execuo: s = dynamic_cast<bar *>(q);

Exemplo: Eiffel

class foo ... class bar inherit foo ... ... f : foo b : bar ... f := b -- b recebe f caso f referencie um -- objeto do tipo bar b ?= f

Virtual x In line
Mtodos virtuais no podem ser expandidos em linha Mtodos curtos com expanso em linha: estticos (no-virtuais)

Polimorsmo
Rotina que opera sobre foo: funciona para qualquer lho de foo Unio dinmica de mtodos: mtodos da classe lha sero chamados Mas no resolve todos os problemas...

Revisando Exemplo de Lista


class list_err { // exceo public: char *description; list_err(char *s){description = s;} }; class list_node { list_node* prev; list_node* next; list_node* head_node; public: int val; list node() { prev = next = head_node = this; val = 0; } list_node* predecessor() { if (prev == this || prev == head_node) return 0; return prev; } list_node* successor() { if (next == this || next == head_node) reuturn 0; return next; } bool singleton() { return (prev == this); } void insert_before(list_node* new_node) { if(!new_node->singleton()) throw new list_err(insero repetida); prev->next = new_node; new_node->prev = prev; new_node->next = this; prev = new_node; new_node->head_node = head_node; } void remove(){ if(singleton()) throw new list_err(n no existe); prev->next = next; next->prev = prev; prev = next = head_node = this; } ~list_node() { if(!singleton()) throw new list_err(n ainda na lista); } };

Revisando Exemplo de Lista


class list{ list_node header; public: int empty() { return header.singleton(); } list_node* head() { return header.successor(); } void append(list_node *new_node) { header.insert_before(new_node); } ~list() { if (!header.singleton()) throw new list_err(Lista no vazia) } };

Revisando Exemplo de Lista

class int_list_node : public_list_node { public: ... void remove() { try{ gp_list_node::remove(); } catch(list_err) { // no faz nada } };

int_list_node *q, r; ... r = q->successor(); // Erro! gp_list_node * p = q->successor(); cout << p.val; // Erro!

Classes Genricas
template <class V> class list_node { list_node<V>* prev; list_node<V>* next; list_node<V>* head_node; public: V val; list_node<V>* predecessor() {... list_node<V>* successor() {... void insert_before(list_node<V>* new_node) {... ... };

template <class V> class list { list_node<V> header; public: list_node<V>* head() {... void append(list_node<V> *new_node) {... ... };

Classes Genricas
typedef list_node<int> int_list_node; typedef list_node<int> int_list; ... int_list numbers; int_list_node* firtst_int; ... first_int = numbers->head();

Tipo genrico: abstrao do tipo Flexibilidade extra No possvel fazer isso com herana

Exemplo
template <class V> class queue : public list <V> { public: void enqueue(list_node<V>* new_node){ append(new_node); } list_node<V>* dequeue(){ if(empty()) throw new list_err(fila vazia); list_node<V>* p = head(); p->remove(); return p; } };

Exemplo: Eiffel
class gp_list_node ... ... class gp_list feature {NONE} -- private header : gp_list_node -- a ser redefindo feature {ALL} -- public head : like header is ... append (new_node : like header) is ... ... end ... class student_list_node inherit gp_list_node ... ... class student_list inherit gp_list redefine header end feature {NONE} header : strudent_list_node -- no preciso redefinir head e append

Fechamento de Objetos

Fechamento de objetos para simular fechamento de rotinas Fechamento: Mtodo + Contexto

Exemplo
template <class T> class un_op{ public: virtual T operator()(T i) const = 0; }; class plus_x : public un_op<int> { const int x; public: plus_x(int n) : x(n) { } virtual int operator()(int i) const { return i + x; } }; void apply_to_A(const un_op<int>& f, int A[], int A_size) { int i; for (i = 0; i < A_size; i++) A[i] = f(A[i]); } ... int A[10]; apply_to_A(plus_x(2), A, 10);

Armazenando Argumentos
Aplicao de fechamento de objetos Fechamento: funo + alguns argumentos Armazena os argumentos para uso posterior

Exemplo
class fn_call { public: virtual void trigger() = 0; }; void schedule_at(fn_call& fc, time t) { ... } ... void foo(int a, double d, char c) { ... } class call_foo : public fn_call { int arg1; double arg2; char arg3; public: call_foo(int a, double b, char c) : arg1(a), arg2(b), arg3(c) {} void trigger() { foo(arg1, arg2, arg3); } }; ... call_foo cf(3, 3.14, x); schedule_at(cf, now() + delay);

Linguagens OO
Linguagens com modelo uniforme de objetos Todo tipo uma classe Toda varivel um objeto Objetos antropomrcos: responsveis por toda computao Smalltalk, Ruby, Python (3)

Smalltalk
Linguagem OO cannica Estruturas de controle so objetos Ambiente de programao um objeto editor interpretador

C++ OO?
No Permite fazer programas OO Coisas no OO de C++: rotinas fora de classes tipos no so classes mtodos so estticos por padro ... mantm compatibilidade com C

Parte III Scripts

Introduo
Linguagens tradicionais: aplicaes auto-contidas Problema comum: coordenao entre de diversos programas Ex.: sistema de folha de pagamento

Introduo
Motivao inicial: juntar programas Foco: exibilidade desenvolvimento rpido adaptaes locais vericaes em tempo de execuo bibliotecas

Scripts e Programao Web


Como gerar contedo dinamicamente num pgina web? Executar um programa Onde? No servidor (server-side) No computador do usurio (client-side)

Server-Side

Controle sobre o contedo da pgina Uso computacional intensivo Manipulao de dados sigilosos

Client-Side

Precisam acessar informaes locais Tempo de execuo crtico Exemplo: animaes, vericao de erros

Scripts CGI
Common Gateway Interface Mecanismo para executar scripts no servidor Viso geral: cliente acessa um endereo servidor executa o script script retorna resultado para o cliente normalmente em HTML

Exemplo

#!/usr/bin/perl print Content-type: text/html\n\n; $host = hostname; chop $host; print <HTML>\n<HEAD>\n<TITLE>Status of , $host, <\TITLE>\n<\HEAD>\n<BODY>\n print <H1>, $host, </H1>\n; print <PRE>\n, uptimem \n, who; print </PRE>\n</BODY>\n<\HTML>\n;

Scripts CGI
Desvantagens: cada acesso: programa separado instalao em diretrios especiais cada script precisa gerar o cdigo HTML

Server-Side Includes
Servidores Web: mdulos de execuo de script Scripts inseridos no cdigo HTML Servidor executa o script e substitui o cdigo pelo resultado Transparente para o usurio

Exemplo
<HTML> <HEAD> <TITLE>Status of <?php echo $host = chop(hostname) ?></TITLE> </HEAD> <BODY> <H1><?php echo $host ?></H1> <PRE> <?php echo uptime, \n, who ?> </PRE> </BODY> </HTML>

Client-Side Scripts

Necessitam de um interpretador no cliente Linguagens mais restritas Mais popular: JavaScript

Python
Criado no nal dos anos 80s Interpretada Imperativa (inuenciada por ling. funcionais) Foco: cdigo legvel facilidade na programao

Interpretador

Executa cdigo linha por linha Forma rpida de testar cdigo Cdigo pode ser armazenado num arquivo

Sistema de Tipos
Tipos so dinmicos Variveis so criadas conforme so utilizadas Modelo por referncia Variveis so nomes para valores Fortemente tipado: Operaes sobre tipos denidos

Tipos Bsicos

string = two # string f = 2.0 # ponto flutuante i = 2 # inteiro b = True # booleano c = 1 + 1j # complexo

Operaes
Adio: + tipos: todos (string = concatenao) Subtrao: tipos: todos - string Multiplicao: * tipos: todos (string = concatenao mult.) Diviso: / tipos: todos - string Resto: % tipos: todos - string Exponenciao: tipos: todos - string Obs.:

+=, -= ,...

Ateno!
Python fortemente tipado:
f1 = 1.0 str = 1 f2 = f1 + 2.0 print f2 str2 = str + 2 print str2 f3 = f1 + str # ERRO f3 = f1 + float(str) # Ok: Converso explcita str3 = str(f1) + str # Ok: Converso explcita

Operaes Lgicas
Igualdade: == Diferente: != Menor/maior: >, < Operadores lgicos: not, and, or

Ordem de Execuo e Escopo


Cada linha executada de cada vez quebra de linha denota o m do comando Escopo delimitados por identao mesma identao: mesmo bloco variveis: escopo por bloco precisam ser denidas antes de serem utilizadas

Tipos de Escopo

Global Local Classe

Tempo de Vida de Objetos


Objetos possuem tempo de vida ilimitado Contagem de referncia Ignora referncia cruzada Coletor de lixo: Executado apenas quando desalocao - alocao > limiar

Estruturas de Controle
Repetio com controle lgico: while Sequenciamento: if / elif Repetio por enumerao: for

while

contador = 3 while contador > 0: print contador contador -= 1

if / elif

temp = 23 if temp < 18: print frio elif temp > 28: print calor else: print normal

Exemplo
num = 2 while num <= 1000: eh_primo = True div = 2 while div**2 <= num: if (num % div) == 0: eh_primo = False div += 1 if eh_primo: print num num += 1

Listas
Container padro em Python Alocao dinmica: tipo mutvel Associao: ndice -> referncia Dados heterogneos Declarao: l = [1.0, 2.0, 3.0] Acesso: l[0] == 1.0, l[1] == 2.0, l[2] == 3.0 l[-1] == 3.0, l[-2] == 2.0, l[-3] == 1.0

Operaes
append: inclui elemento ao nal da lista del: exclui elementos len: nmero de elementos
l = [1.0] l.append(Jose) l.append(1 + 1j) del l[1] print l #[1.0, (1+1j)] print len(l) # 2

Listas Aninhadas

pessoa1 = [Joao, 20] pessoa2 = [Jose, 30] dados = [pessoa1, pessoa2] dados[0][1] = 21 print pessoa1[1] # 21

Operador is
Teste de identidade Verica se duas referncias apontam para o mesmo objeto
l1 = [1] l2 = l1 l3 = [1] l4 = [l1] print l1 is l2 # True print l1 is l3 # False print l1 is l4[0] # True

Operador in
Pertence ou no pertence

l1 = [1] l2 = l1 l3 = [1] l4 = [l1] print 1 in l2 # True print l2 in l1 # False print l1 in l4 # True

Iterando sobre Listas


loop for itera sobre elementos de uma lista

l = [1, Joao, 1+1j, 3.5] for item in l: print item

Funo Range
Retorna lista inteiros dentro de um conjunto

i = range(10) # 0..9 i = range(1, 10) # 1..9 i = range(1, 10, 2) # 1, 3, 5, 7, 9

lista = [... for ind in range(len(lista)): print ind, lista[ind]

Cortes de Listas

i = range(10) print i[0:-1] print i[2:5] print i[2:9:2] print i[-1:0:-1] print i[0:] print i[:-1] print i[:0:-1] print i[::-1] print i[::]

# # # # # # # # # #

0..9 [0, 1, [2, 3, [2, 4, [9, 8, [0, 1, [0, 1, [9, 8, [9, 8, [0, 1,

2, 4] 6, 7, 2, 2, 7, 7, 2,

3, 4, 5, 6, 7, 8] 8] 6, 3, 3, 6, 6, 3,

5, 4, 4, 5, 5, 4,

4, 5, 5, 4, 4, 5,

3, 6, 6, 3, 3, 6,

2, 7, 7, 2, 2, 7,

1] 8, 9] 8] 1] 1, 0] 8, 9]

Obs.: Funciona com strings tambm!

Cortes de Listas

i = range(10) i[0:3] = [1, 1, 1] print i j = i[3:6] j[0] = 4 print j print i

# 0..9 # [1, 1, 1, 3, 4, 5, 6, 7, 8, 9]

# [4, 4, 5] # [1, 1, 1, 3, 4, 5, 6, 7, 8, 9]

Dicionrios
Alocao dinmica: tipo mutvel Associao: chave -> valor Dados heterogneos Declarao: d = {a:1.0, c:2.0, 3:3.0} Acesso: d[a] == 1.0, d[c] == 2.0, d[3] == 3.0

Exemplos
l = [1, 2, 3] d = {a:1, 2:3, 1+1j:5, l:1.0} # ERRO d = {a:1, 2:3, 1+1j:5, 1:l} print d.keys() # ['a', 1, 2, (1+1j)] print d.values() # [1, [1, '2', 3], 3, '5'] d[1][2] = 2 print l # [1, '2', 2] print d # {'a': 1, 1: [1, '2', 2], 2: 3, (1+1j): '5'} for item in d: print item # imprime os valores print d.has_key(1+1j) # True

Set

Parecido com dicionrio No possui elementos repetidos No tem chave

Tuple
t = (1, a, c) t[0] == 1 t[1] == a Tuple imutvel: t[0] = 2 # ERRO!

Tuple
Parnteses podem ser omitidos t = 1, 2, 3 Tuple pode ser desempacotado: item1, item2, item3 = t item1, item2, item3 = 1, 2, 3

Funes
Variveis de primeira classe Parmetros: no possuem tipo passagem por referncia podem ter valores padro podem ser nomeados sempre retornam um valor

Funes: Sintaxe
def hello(): print hello >>> hello() # hello def hello(nome): aux = hello, + nome print aux >>> hello(Eu) # Hello, Eu def add(a): b = a + 1 return b >>> c = add(1) >>> print c # 2 >>> c = add(test) # ERRO

Funes - Retornos

def sign(num): if num > 0: return 1 elif num < 0: return -1 else: return 0

def hello(): print hello >>> temp = hello() >>> print type(hello) # None

Exemplos
def add(arg): return 1 + arg

def add(arg): if type(arg) == Int return 1 + arg elif type(arg) == Str return erro

RUIM

def add(arg): try: return 1 + arg except: return erro

BOM

Funo: Referncias

def appender(a_string, a_list): a_string += test a_list.append(test) >>> my_str = test >>> my_list = [test] >>> appender(my_str, my_list) >>> print my_str >>> print my_list

Funes: Argumentos

def adjust_value(value, amount=2.0): return value * amount >>> print adjust_value(1.0) >>> print adjust_value(1.0, 3.0)

Funes: Argumentos

def adjust_value(value, amount=2.0, thr=1.0): if value > thr: return value * amount return value >>> print adjust_value(value=1.0, amount=2.0, thr=3.0) >>> print adjust_value(thr=3.0, amount=2.0, value=1.0) >>> print adjust_value(value=1.0, thr=2.0) >>> print adjust_value(thr=2.0, amount=1.0) # ERRO

Funes: Escopo
>>> aux = 1.0 def scope_test(): aux = 2.0 >>> scope_test() >>> print aux # 1.0 def scope_test_2(): a = aux return a >>> print scope_test_2() # 1.0 def scope_test_3(): global aux aux = 2.0 >>> scope_test_3() >>> print aux # 2.0 def scope_test_4(): a = aux aux = 2 >>> scope_test_4() # ERRO

Funes: Variveis
def hello(): print Hello >>> hello_alias = hello >>> print hello_alias() # Hello

>>> PI = 3.141592654 def area(r): return r * r * PI def circ(r): return 2 * r * PI >>> func = [area, circ] >>> for foo in func: print foo(1.0)

Funes de Alto Nvel


def call_it(func, value): return func(value) def do_all(func, values): result = [] for val in values: result.append(func(val)) return result def combine_values(func, values): current = values[0] for i in range(1, len(values)): current = func(current, values[i]) def add(x, y): return x + y def mult(x, y): return x * y >>> print combine_values(add, [1, 3, 5]) >>> print combine_values(mult, [1, 3, 5])

Funes: Argumentos

def add_all(*args): total = None for a in args: total += a return total >>> print add_all() >>> print add_all(1) >>> print add_all(1, 2, 3) >>> print add_all(1, 2, 3)

Funes: Argumentos

def combine_values(func, *values): current = values[0] for i in range(1, len(values)): current = func(current, values[i]) >>> print combine_values(add, 1, 2, 3)

Funes: Prog. Funcional


lter(f, s): seleciona elementos de s em que f verdadeiro map(f, s): aplica f nos elementos de s reduce(f, s): usa f para combinar todos os elementos de s

Funes: Prog. Funcional

def >>> def >>> def >>>

positive(x): return x >= 0 print filter(positive, [-3, -2, -1, 0, 1, 2]) negate(x): return -x print map(negate, [-3, -2, -1, 0, 1, 2]) add(x, y): return x + y print reduce(add, [-3, -2, 0, 1, 2])

Mdulo
modulo.py
def add(x, y): return x + y def sub(x, y): return x - y >>> >>> >>> >>> >>> import modulo x = 1 y = 1 print modulo.add(x, y) print modulo.sub(x, y)

Classes

class Vazia(object): pass # No faz nada >>> >>> >>> >>> nada_1 = Vazia() nada_2 = Vazia() print nada_1 is nada_2 # False print nada_1 is Nada # False

Mtodos

class Vazia(object): def nada(self): print Nada >>> nada_1 = Vazia() >>> nada_1.nada() # Nada >>> nada_1.nada() # Chamada: nada(nada_1)

Atributos

class Greeter(object): def greet(self, name): print self.hello + name + ! >>> g = Greeter() >>> g.hello = Ola, >>> g.greet(Joao) # Ola, Joao!

Construtor
class Greeter(object): def __init__(self, hello): self.hello = hello def greet(self, name): print self.hello + name + ! >>> >>> >>> >>> g = Greeter(Ola, g.greet(Joao) # g.hello = Hello, g.greet(John) # ) Ola, Joao! Hello, John!

Cuidado

class Greeter(object): def __init__(self, hello_msg): hello = hello_msg def greet(self, name): print self.hello + name + ! >>> g = Greeter(Ola, ) >>> g.greet(Joao) # ERRO

Interfaces
Interface x Implementao Interface: o que alguma coisa sabe fazer Implementao: como ela faz coisas Exemplo de como usar interfaces em Python: Srio com amostras irregularmente amostradas

Exemplo
Sinal amostrado irregularmente Esconder a amostragem irregular Como reamostrar o sinal? Constante por partes Interpolao linear Filtro mais sosticado

Exemplo
Interface desejada:
class AlgumNome(object): def __init__(self, values): valores = ((x0, y0), (x1, y1), ...) # guardar valores def get(self, where): # verificar se where est na faixa permitida # retornar valor interpolado

Exemplo
Implementao - constante por partes
class SinalDegrau(object): ... def get(self, where): if where < self.values[0][0]: raise IndexError(Indice muito pequeno) for i in range(len(values)-1): x0, y0 = self.values[i] x1, y1 = self.values[i+1] if x0 <= where <= x1: return y0 raise IndexError(Indice muito pequeno)

Exemplo
Interpolao linear

class SinalLinear(object): ... def get(self, where): if where < self.values[0][0]: raise IndexError(Indice muito pequeno) for i in range(len(values)-1): x0, y0 = self.values[i] x1, y1 = self.values[i] if x0 <= where <= x1: return y0 + (y1-y0) * (where-x0) / (x1-x0) raise IndexError(Indice muito pequeno)

Exemplo
Aplicao:

def average(signal, x0, x1, num_samples): width = (x1 - x0) / num_samples total = 0.0 for i in range(num_samples): x = x0 + i * width total += signal.get(x) return total / num_samples

Herana
class Pai(object): def hello(self): print Hello class Filho(Pai): def goodbye(self): print Goodbye >>>c = Filho() >>>c.goodbye() >>>c.hello()

def get(self, x): return self.amp * math.sin(x * self.freq)

Exemplo
class SinalInterpolado(object): def find(self, where): if where < self.values[0][0]: raise IndexError(Indice muito pequeno) for i in range(len(values)-1): x0, y0 = self.values[i] x1, y1 = self.values[i] if x0 <= where <= x1: return i raise IndexError(Indice muito pequeno)

Exemplo

class SinalDegrau(SinalInterpolado): def __init__(self, values): self.values = values def get(self, where): i = self.find(where) return self.values[i][1]

Exemplo
class SinalInterpolado(object): def __init__(self, values): self.values = values[:] def get(self, where): raise NotImplemented def find(self, where): if where < self.values[0][0]: raise IndexError(Indice muito pequeno) for i in range(len(values)-1): x0, y0 = self.values[i] x1, y1 = self.values[i] if x0 <= where <= x1: return i raise IndexError(Indice muito pequeno)

Exemplo
class SinalDegrau(SinalInterpolado): def __init__(self, values): super().__init__(values) def get(self, where): i = self.find(where) return self.values[i][1]

class SinalLilnear(SinalInterpolado): def __init__(self, values): super().__init__(values) def get(self, where): i = self.find(where) return y0 + (y1-y0) * (i-x0) / (x1-x0)

Sobrecarga
Classe para vetores Sobrecarga: len(vec) vec[i]

Vetor sem Sobrecargas


class Vetor(object): def __init__(self, len): self.values = {} self.len = len def get(self, index): self.check_index(index) return self.values[index] def set(self, i, value): self.check_index(index) self.values[index] = i def check_index(self, index): if (index < 0) or (index >= len): IndexError(Index out of range)

Sobrecarga
Quase tudo em Python uma chamada para um mtodo len(x) --> x.__len__() a = x[0] --> a = x.__getitem__(0) x[0] = 1 --> x.__setitem__(0, 1)

Exemplo
class Vetor(object): def __init__(self, len): self.values = {} self.len = len def __getitem__(self, index): self.check_index(index) return self.values[index] def __setitem__(self, i, value): self.check_index(index) self.values[index] = i def __len__(self): return self.len def check_index(self, index): if (index < 0) or (index >= len): IndexError(Index out of range)

Outros Mtodos
__add__ __sub__ __mul__ (__rmul__) __str__ __iter__

Iteradores
Duas formas: objetos iteradores geradores (generators) Vamos ver objetos iteradores

Objeto Iteradores
Possuem um mtodo next(): retorna o prximo elemento Quando chega ao m: Exceo StopIteration Deve continuar dando StopIteration aps chamdas subsequentes Possuem o mtod __iter__(): Retorna ele mesmo

Exemplo
class Vetor(object): ... class VetorIterator(object): def __init__(self, obj): self.obj = obj self.last = 0 def next(self): if self.last >= len(obj): raise StopIteration self.last += 1 return obj[i] def __iter__(self): return self def __iter__(self): return VetorIterator(self)

Вам также может понравиться