Exame-1-2010 - Técnico Lisboa

Propaganda
Instituto Superior Técnico
Programação Avançada –
2009/2010
Primeiro Exame/Segundo Teste –
19/6/2010
Número:
Nome:
Escreva o seu número em todas as folhas da prova. O tamanho das respostas deve ser limitado ao espaço
fornecido para cada pergunta. Pode usar os versos das folhas para rascunho. A prova tem 6 páginas e a
duração é de 2.0 horas. A cotação de cada questão encontra-se indicada entre parêntesis. Boa sorte.
Se pretende fazer o Segundo Teste responda apenas às perguntas 7, 8, 9, 10, 11, 12 e 13.
Se pretende fazer o Exame responda a todas as perguntas.
1. (1.0) Para permitir instrospecção, a linguagem Java teve de reificar o conceito de classe e disponibilizar formas de obter uma classe a partir de uma sua instância ou, na falta desta, a partir do
nome da classe ou, na falta deste, a partir de uma String contendo esse nome. Exemplifique,
com pequenos fragmentos de programas Java, estas três formas diferentes de aceder a uma
classe.
"I am a string".getClass()
String.class
Class.forName("java.lang.String")
2. (1.0) Considere uma hipotética definição de uma métrica da complexidade de uma classe como
sendo a soma do número total de fields públicos descritos nessa classe com o número total de
métodos públicos descritos nessa classe.
Escreva, em Java, uma classe denominada Metricas contendo um método estático denominado complexidade. Este método recebe uma String com o nome de uma classe e devolve
um inteiro com o valor da complexidade dessa classe.
import java.lang.reflect.*;
class Metricas {
public static int complexidade(String c) throws ClassNot
Class objClass = Class.forName(c);
return objClass.getFields().length + objClass.getMet
}
}
Número:
2
3. (1.0) A linguagem Lisp inventou o quote e, posteriormente, o backquote. Para que servem? Como
funcionam?
Quer o quote, quer o backquote servem para facilitar a metaprogramação. O quote indica que o seu argumento é para ser tomado literalmente, sem avaliação, permitindo que fragmentos de programas possam ser tratados como dados. O backquote funciona de
modo idêntico mas permite selectivamente avaliar subexpressões do
seu argumento, precedendo-as do comma. Desta forma, o backquote
comporta-se como um mecanismos de templates que facilita substancialmente a meta-programação.
4. (2.0) Várias propostas têm surgido para a inclusão de despacho múltiplo em Java. Explique este conceito e especule relativamente às vantagens e desvantagens que a sua implementação poderá
ter em Java. Em particular, compare-o com o já existente conceito de overloading.
5. (2.0) Em CLOS, a aplicação de uma função genérica pode implicar a computação do método efectivo.
Descreva as etapas dessa computação.
(a) São seleccionados os métodos aplicáveis.
(b) Os métodos seleccionados são ordenadas do mais especı́fico para o
menos especı́fico.
(c) Os métodos ordenados são combinados, produzindo o método
efectivo.
6. (3.0) Pretende-se adaptar o modelo de orientação a objectos da linguagem Java de modo a permitir
a utilização de valores activos. Um valor activo é um objecto Java que, quando modificado,
notifica outros objectos de que isso aconteceu.
A tı́tulo de exemplo, considere um objecto Java que representa um automóvel em movimento
e cuja classe tem a seguinte definição:
Número:
3
class Automovel extends ... {
String marca;
String modelo;
...
float velocidadeActual;
...
}
Dada uma instância de um automóvel, pretende-se que seja possı́vel associar-lhe um ou mais
objectos (que denominaremos listeners) de tal modo que os objectos serão notificados através
da invocação de um método pré-combinado que receberá, como argumento, o objecto que foi
modificado. Por exemplo, poderá ser possı́vel associar a um automóvel especı́fico um objecto
gráfico que represente um velocı́metro onde a velocidadeActual desse automóvel seja continuamente apresentada à medida que o automóvel vai mudando de velocidade.
Tendo este cenário em conta, proponha um mecanismo de intercessão baseado em Javassist
que facilite a criação de valores activos. Não é necessário apresentar a implementação do seu
mecanismo mas inclua toda a informação que considerar relevante para que outra pessoa possa
realizar essa implementação sem problemas.
4
Número:
7. (2.0) Em geral, a programação orientada a aspectos permite não só o cross-cutting dinâmico mas
também o cross-cutting estático. Quais são as capacidades inerentes a cada um destes conceitos?
Explique.
O cross-cutting dinâmico implica a modificação do comportamento de
um programa, permitindo a inserção de comportamento adicional em
pontos bem definidos da execução do programa.
O cross-cutting estático implica a modificação da estrutura estática do
programa, permitindo modificações na hierarquia de classes, a adição
de métodos, a implementação de novas interfaces, etc.
8. (1.0) Descreva, por palavras suas, qual o efeito do seguinte aspecto em AspectJ:
aspect FooAspect {
static final int LIMIT = 100;
before(Foo foo, int newBar):
set(int Foo.bar) && target(foo) && args(newBar) {
if (Math.abs(newBar - foo.bar) > LIMIT) {
throw new RuntimeException();
}
}
}
9. (2.0) A enorme maioria das linguagens de programação inclui dois conceitos relacionados com a
associação de nomes a valores: definição e atribuição.
5
Número:
(a) (1.0) Em termos da linguagem de programação, qual é a diferença entre estes dois conceitos?
(b) (1.0) Em termos da implementação dessa linguagem num avaliador meta-circular, qual é a
diferença entre estes dois conceitos?
10. (1.0) A linguagem Common Lisp providencia as formas function (#’) e funcall, enquanto que
a linguagem Scheme não as possui. Porquê? Explique.
11. (1.0) Discuta as diferenças entre iteradores externos (external iterators) e iteradores internos (internal
iterators).
• An Internal Iterator is a higher-order function that applies a function to each element of a collection.
– The iteration is controlled by the producer of values.
– Used in Lisp, Haskell and other Functional Languages.
6
Número:
• An External Iterator is an accessor of the current element of a collection, and, potentially, of the next one.
– The iteration is controlled by the consumer of values.
– Used in C++, Java and other Object-Oriented Languages.
12. (1.0) Considere o operador yield tal como é usado na linguagem Python para a criação de geradores (generators). Explique como é que poderia implementar esse operador numa linguagem
que permita a captura de continuações.
Teria de capturar uma continuação na invocação do gerador para poder retornar um valor ao consumidor assim que se atinge o operador
yield. Nesse momento, teria de capturar outra continuação para guardar o estado de computação do gerador para, na invocação seguinte,
poder retormar a execução do mesmo. Esta continuação teria de ser
guardada entre invocações do gerador.
13. (2.0) Considere o operador ambı́guo amb, proposto por John McCarthy, que não-deterministicamente
retorna o valor de uma das expressões dadas como argumento.
(a) (1.0) Utilizando operador amb, defina uma função denominada inteiro-maior-ou-igual-a
que recebe um inteiro como argumento e que, não-deterministicamente, retorna um inteiro
maior ou igual ao argumento.
(define (inteiro-maior-ou-igual-a a)
(amb a
(inteiro-maior-ou-igual-a (+ a 1))))
(b) (1.0) Considere ainda o operador fail. Juntamente com o operador amb, defina uma função
elemento-lista que recebe uma lista como argumento e que não-deterministicamente
retorna um elemento dessa lista.
(define (elemento-lista l)
(if (null? l)
(fail)
(amb (car l)
(elemento-lista (cdr l)))))
Download