2.2.4 Exemplo: Uma Linguagem de Imagens
Esta seção apresenta uma linguagem simples para desenhar imagens que ilustra o poder da abstração de dados e da propriedade de closure. A linguagem é projetada para tornar fácil experimentar padrões como os desenhos do artista M.C. Escher.
Fundamentos da Linguagem
A linguagem tem apenas um tipo de elemento, chamado painter (pintor). Um painter desenha uma imagem que é deslocada e escalada para se ajustar dentro de um paralelogramo especificado chamado frame (quadro).
Frames
Um frame pode ser descrito por três vetores—um vetor de origem e dois vetores de borda. O frame coordena o processo de desenho:
- O vetor de origem especifica o deslocamento da imagem
- Os vetores de borda especificam a escala e orientação da imagem
Painters
Painters são funções que recebem um frame como argumento e desenham sua imagem transformada para se ajustar ao frame. Por exemplo:
wave- desenha uma figura de linharogers- desenha uma foto de William Barton Rogerseinstein- desenha uma foto de Albert Einstein
Combinando Painters
A linguagem fornece operações que criam novos painters a partir de painters existentes:
Transformações Simples
Carregando playground de código...
Composição
Carregando playground de código...
Closure e Abstração
Como beside e below retornam painters, podemos usá-los como building blocks para padrões cada vez mais complexos:
Carregando playground de código...
Design Estratificado
Esta linguagem de imagens ilustra o design estratificado—a noção de que um sistema complexo deve ser estruturado como uma sequência de níveis descritos usando uma sequência de linguagens. Cada nível é construído combinando partes que são consideradas primitivas naquele nível, e as partes construídas em cada nível são usadas como primitivas no próximo nível.
A abordagem de design estratificado ajuda a tornar os programas robustos—pequenas mudanças na especificação se traduzem em pequenas mudanças no programa.
Exercícios
Exercício 2.44: Defina a função up_split usada por corner_split. Ela é similar a right_split, exceto que troca os papéis de below e beside.
Exercício 2.45: right_split e up_split podem ser expressas como instâncias de uma operação geral de divisão. Defina uma função split que permita definir ambas.
Exercício 2.46-2.49: Implemente a representação de vetores e frames, e defina um painter primitivo segments_painter que desenha uma lista de segmentos de linha.
Exercício 2.50-2.52: Defina transformações de painters (flip_horiz, rotate180, rotate270) e crie novos níveis de padrões combinando corner_split e square_limit de maneiras diferentes.
📝 Encontrou algo errado nesta página?
Sua ajuda é muito importante para melhorar a qualidade da tradução!
🐛 Encontrou um erro?
Se você encontrou:
- Erro de tradução (palavra incorreta, termo técnico errado)
- Erro de ortografia ou gramática
- Link quebrado
- Código de exemplo que não funciona
- Problema de formatação
❓ Tem uma dúvida?
Se você tem:
- Dúvida sobre o conteúdo desta seção
- Pergunta sobre um conceito do SICP
- Dificuldade em entender algum exemplo
- Questão sobre a tradução de algum termo
💡 Tem uma sugestão de melhoria?
Se você quer sugerir:
- Melhoria na explicação
- Exemplo adicional
- Recurso visual (diagrama, ilustração)
- Qualquer outra ideia
🌍 Quer discutir a tradução?
Se você quer debater:
- Escolha de tradução de algum termo
- Consistência de terminologia
- Nuances do português
Obrigado por ajudar a melhorar o SICP.js PT-BR! ✨