Polimorfismo ad hoc - Ad hoc polymorphism

Em linguagens de programação , o polimorfismo ad hoc é um tipo de polimorfismo no qual funções polimórficas podem ser aplicadas a argumentos de diferentes tipos, porque uma função polimórfica pode denotar uma série de implementações distintas e potencialmente heterogêneas, dependendo do tipo de argumento (s) para o qual é aplicado. Quando aplicado a conceitos orientados a objetos ou procedurais, também é conhecido como sobrecarga de função ou sobrecarga de operador . O termo ad hoc neste contexto não tem a intenção de ser pejorativo; refere-se simplesmente ao fato de que esse tipo de polimorfismo não é uma característica fundamental do sistema de tipos . Isso contrasta com o polimorfismo paramétrico , no qual funções polimórficas são escritas sem menção a nenhum tipo específico e, portanto, podem aplicar uma única implementação abstrata a qualquer número de tipos de maneira transparente. Esta classificação foi introduzida por Christopher Strachey em 1967.

Encadernação antecipada

O polimorfismo ad hoc é um mecanismo de despacho : o controle que se move através de uma função nomeada é despachado para várias outras funções sem ter que especificar a função exata que está sendo chamada. A sobrecarga permite que várias funções de diferentes tipos sejam definidas com o mesmo nome; o compilador ou interpretador garante automaticamente que a função correta seja chamada. Dessa forma, funções anexando listas de inteiros , listas de strings , listas de números reais e assim por diante podem ser escritas, e todas podem ser chamadas de anexar - e a função anexar correta seria chamada com base no tipo de lista sendo anexada. Isso difere do polimorfismo paramétrico, no qual a função precisaria ser escrita genericamente , para funcionar com qualquer tipo de lista. Usando a sobrecarga, é possível que uma função execute duas coisas completamente diferentes com base no tipo de entrada transmitida a ela; isso não é possível com polimorfismo paramétrico. Outra maneira de ver a sobrecarga é que uma rotina é identificada exclusivamente não por seu nome, mas pela combinação de seu nome e o número, ordem e tipos de seus parâmetros.

Esse tipo de polimorfismo é comum em linguagens de programação orientadas a objetos , muitas das quais permitem que os operadores sejam sobrecarregados de maneira semelhante às funções (consulte sobrecarga de operador ). Algumas línguas que não são digitados de forma dinâmica e carecem ad polimorfismo hoc (incluindo classes de tipo) têm nomes de função mais longos, como print_int, print_string, etc. Isto pode ser visto como vantagem (mais descritivo) ou uma desvantagem (excessivamente detalhado), dependendo do ponto de vista .

Uma vantagem que às vezes é obtida com a sobrecarga é a aparência de especialização, por exemplo, uma função com o mesmo nome pode ser implementada de várias maneiras diferentes, cada uma otimizada para os tipos de dados específicos em que opera. Isso pode fornecer uma interface conveniente para o código que precisa ser especializado em várias situações por motivos de desempenho. A desvantagem é que o sistema de tipos não pode garantir a consistência das diferentes implementações.

Uma vez que a sobrecarga é feita em tempo de compilação, ela não é um substituto para a ligação tardia, conforme encontrada no polimorfismo de subtipagem .

Ligação tardia

Não obstante a seção anterior, existem outras maneiras pelas quais o polimorfismo ad hoc pode funcionar. Considere, por exemplo, a linguagem Smalltalk. Em Smalltalk , a sobrecarga é feita em tempo de execução, pois os métodos ("implementação da função") para cada mensagem sobrecarregada ("função sobrecarregada") são resolvidos quando estão prestes a serem executados. Isso acontece em tempo de execução, após a compilação do programa. Portanto, o polimorfismo é fornecido pela subtipagem de polimorfismo como em outras linguagens, e também é estendido em funcionalidade por polimorfismo ad hoc em tempo de execução.

Um exame mais detalhado também revelará que Smalltalk fornece uma variedade ligeiramente diferente de polimorfismo ad hoc . Como Smalltalk tem um modelo de execução de limite tardio e fornece aos objetos a capacidade de manipular mensagens que não são compreendidas, é possível implementar a funcionalidade usando polimorfismo sem sobrecarregar explicitamente uma mensagem específica. Isso pode não ser uma prática geralmente recomendada para a programação diária, mas pode ser bastante útil ao implementar proxies.

Além disso, embora em termos gerais o método de classe comum e a sobrecarga do construtor não sejam considerados polimorfismo, existem linguagens mais uniformes nas quais as classes são objetos regulares. Em Smalltalk, por exemplo, classes são objetos regulares. Por sua vez, isso significa que as mensagens enviadas às classes podem ser sobrecarregadas, e também é possível criar objetos que se comportam como classes sem que suas classes herdem da hierarquia de classes. Essas são técnicas eficazes que podem ser usadas para tirar proveito dos poderosos recursos de reflexão do Smalltalk . Arranjos semelhantes também são possíveis em linguagens como Self e Novilíngua .

Exemplo

Imagine um operador +que pode ser usado das seguintes maneiras:

  1. 1 + 2 = 3
  2. 3.14 + 0.0015 = 3.1415
  3. 1 + 3.7 = 4.7
  4. [1, 2, 3] + [4, 5, 6] = [1, 2, 3, 4, 5, 6]
  5. [true, false] + [false, true] = [true, false, false, true]
  6. "bab" + "oon" = "baboon"

Sobrecarregando

Para lidar com essas seis chamadas de função, quatro partes diferentes de código são necessárias - ou três , se as strings forem consideradas listas de caracteres:

Assim, o nome +na verdade se refere a três ou quatro funções completamente diferentes. Este é um exemplo de sobrecarga . (Observe a ambigüidade nos tipos de string usados ​​no último caso. Considere "123" + "456" em que o programador pode naturalmente assumir adição em vez de concatenação. Eles podem esperar "579" em vez de "123456". A sobrecarga pode, portanto, fornecer significado ou semântica diferente para uma operação, bem como implementações diferentes.)

Referências