2.5.2 Combinando Dados de Diferentes Tipos
Ignoramos uma questão importante ao implementar as operações aritméticas genéricas: as operações que definimos até agora tratam objetos de um único tipo. O que fazer se queremos manipular objetos de tipos diferentes, como adicionar um número complexo a um número ordinário?
Operações entre Tipos
Uma maneira de lidar com operações entre tipos é projetar um procedimento diferente para cada combinação possível de tipos. Por exemplo, poderíamos ter:
Carregando playground de código...
No entanto, este enfoque rapidamente se torna inviável à medida que adicionamos mais tipos ao sistema.
Coerção
Uma maneira mais geral de lidar com operações entre tipos é usar coerção. Muitas vezes podemos ver um tipo como um caso especial de outro tipo. Por exemplo, um número inteiro pode ser visto como um número racional cujo denominador é 1, ou um número ordinário pode ser visto como um número complexo cuja parte imaginária é zero.
Carregando playground de código...
Agora podemos modificar apply_generic para tentar coerção se não houver operação direta disponível:
Carregando playground de código...
Hierarquia de Tipos (Torre)
Em muitos casos, os tipos podem ser organizados em uma torre onde cada tipo tem no máximo um supertipo e um subtipo. Por exemplo:
inteiro → racional → real → complexo
Nessa hierarquia, podemos simplificar a coerção "elevando" sucessivamente tipos até que ambos os argumentos estejam no mesmo nível:
Carregando playground de código...
Limitações
Nem todos os sistemas de tipos podem ser organizados em uma torre simples. Em sistemas do mundo real, os tipos frequentemente têm múltiplos supertipos e subtipos, criando complexidade significativa no gerenciamento de operações genéricas.
Exercícios
Exercício 2.81: Louis Reasoner nota que apply_generic pode tentar forçar argumentos para seu próprio tipo. Modifique apply_generic para que não tente coerção se os dois argumentos já têm o mesmo tipo.
Exercício 2.82: Mostre como generalizar apply_generic para lidar com coerção no caso geral de múltiplos argumentos.
Exercício 2.83: Suponha que você está projetando um sistema aritmético genérico para lidar com a torre de tipos mostrada acima. Para cada tipo (exceto complexo), projete uma função raise que eleva objetos daquele tipo um nível na torre.
Exercício 2.84: Usando a função raise do exercício 2.83, modifique a função apply_generic para que ela força seus argumentos para terem o mesmo tipo pelo método de sucessivamente elevar o argumento de tipo mais baixo até que todos os argumentos tenham o mesmo tipo.
Exercício 2.85: Esta seção mencionou um método para "simplificar" um objeto de dados movendo-o para baixo na torre de tipos tanto quanto possível. Projete uma função drop que realiza a simplificação.
Exercício 2.86: Suponha que queremos lidar com números complexos cujas partes real e imaginária são elas mesmas números ordinários, números racionais ou outros números para os quais operações aritméticas genéricas são definidas. Descreva e implemente as mudanças ao sistema necessárias para acomodar isso.
📝 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! ✨