Como um sistema de tipo estático afeta o design de uma linguagem baseada em protótipo?

15

O artigo da Wikipédia sobre idiomas baseados em protótipos contém o seguinte parágrafo:

Almost all prototype-based systems are based on interpreted and dynamically typed languages. Systems based on statically typed languages are technically feasible, however.

De que maneiras um sistema de tipo estático impõe restrições ou apresenta complexidade na linguagem baseada em protótipos, e por que há mais linguagens de protótipos tipados dinamicamente?

    
por Joe 22.07.2011 / 14:37
fonte

3 respostas

6

A fronteira entre um tipo fundamental e um objeto é desfocada e, muitas vezes, introduzida artificialmente. Por exemplo, em C, uma struct é apenas um monte de registros, apenas um tipo não-objeto derivado. Em C ++, uma struct é uma classe com todos os campos public, um objeto. Ainda assim, o C ++ é quase totalmente compatível com o C ... a borda é realmente macia aqui.

Para programação baseada em protótipo, você precisa ter objetos mutáveis em tempo de execução. Eles devem ser de tipo macio porque cada um muda em tempo de execução, uma classe de um tipo muda para outro - seu tipo muda.

Você pode manter tipos não-objeto fundamentais e derivados como estáticos. Mas isso introduz uma disparidade estranha, os objetos são de tipo macio, os não-objetos são tipados com estática, e um hard barier deve ser estabelecido entre os dois. Você deveria ser capaz de transformar uma estrutura? Uma linha? O número deve ser uma classe ou um tipo fundamental, ou um conjunto de tipos fundamentais, int / float / bignum / etc?

É apenas mais natural e fácil de aprender, usar e escrever para ter esse uniforme, todos os tipos são mutáveis ou nenhum tipo é mutável em tempo de execução. Se você declarar apenas um tipo (Object) é mutável, você acaba com dores de cabeça e problemas de ambos os mundos.

O tipo estático é:

  • mais fácil de implementar
  • mais rápido / mais eficiente
  • mais seguro
  • mais fácil de manter / documentar sistemas grandes devido à abstração.

O tipo dinâmico é:

  • mais rápido para escrever,
  • mais conciso
  • linguagem mais fácil de aprender
  • mais perdoável por erros de design.

Ao misturar os dois, você se sacrifica muito.

  • A implementação torna-se mais difícil do que qualquer uma das duas anteriores.
  • a velocidade depende se você usa os tipos flexíveis ou não ... Se fizer isso, é baixo, se você não o fizer, por que escolher o idioma?
  • segurança de tipo está fora da janela para todos os tipos de objeto.
  • seguir como um tipo se transforma em outro é uma tarefa bastante difícil. Documentando isso - muito difícil.
  • Você ainda precisa fazer toda a contabilidade com tipos fundamentais, o que mata a concisão e a velocidade de gravação
  • A complexidade da linguagem é maior (mais difícil de aprender) do que qualquer uma das "específicas",
  • "perdoar" de um tipo dinâmico é substituído pela tendência a alguns erros muito complicados em tipos de atributos incompatíveis.
por 22.07.2011 / 15:42
fonte
3

A dificuldade é bastante direta de se ver: Tomando a visão de objetos como dicionários de métodos, ou como coisas que respondem a mensagens, observe o seguinte sobre linguagens OO comuns tipicamente tipadas:

  • Todas as chaves / mensagens do dicionário geralmente são declaradas com antecedência, usando identificadores declarados estaticamente.

  • Determinados conjuntos de mensagens são declarados antecipadamente e os objetos são associados a esses conjuntos para determinar quais mensagens eles respondem.

  • As relações de inclusão de um conjunto de mensagens sendo um subconjunto de outro são declaradas estaticamente e explicitamente; subconjuntos não declarados, mas lógicos, não são válidos.

  • A verificação de tipo tenta garantir que todas as mensagens sejam enviadas apenas para objetos que respondem a elas.

Cada um desses conflitos, em certa medida, com um sistema baseado em protótipos:

  • Nomes de mensagens podem ser declarados antecipadamente, na forma de "átomos" ou cadeias de caracteres internas ou outros enfeites, mas pouco mais; a plasticidade dos objetos significa que atribuir tipos a métodos é desajeitado.

  • É indiscutivelmente a característica essencial de um sistema baseado em protótipos que conjuntos de mensagens são definidos pelo que um objeto responde, e não o contrário. Seria razoável atribuir aliases a determinadas combinações em tempo de compilação, mas os conjuntos de mensagens determinados em tempo de execução devem ser possíveis.

  • O impacto real dos dois itens acima atinge os relacionamentos de inclusão, onde as declarações explícitas são completamente impraticáveis. A herança no sentido de subtipagem nominal estática é antitética a um sistema baseado em protótipos.

O que nos leva ao ponto final, que nós não realmente queremos mudar. Ainda gostaríamos de garantir que as mensagens sejam enviadas apenas para objetos que respondem a elas. No entanto:

  • Não podemos saber estaticamente quais mensagens podem ser agrupadas.
  • Não podemos saber quais agrupamentos são subconjuntos de outros.
  • Não podemos saber quais agrupamentos são possíveis.
  • Não podemos nem mesmo especificar que tipo de argumentos são enviados junto com uma única mensagem.
  • Basicamente, descobrimos que não podemos especificar muito de nada no caso totalmente geral.

Então, como isso pode ser trabalhado? Ou limita a generalidade completa de alguma forma (o que é desagradável, e pode matar rapidamente qualquer benefício de usar um sistema baseado em protótipos), ou torna o sistema de tipos muito mais fluido e expressa restrições em vez de tipos exatos .

O sistema de tipos baseado em restrições leva rapidamente à noção de sub-digitação estrutural , que, em um sentido muito solto pode ser pensado como o equivalente estático da "tipagem de pato". Os maiores obstáculos aqui são que tais sistemas são muito mais complicados de digitar e são menos conhecidos (o que significa pouco trabalho prévio para estudar).

Em resumo: é possível, é mais difícil de fazer do que um sistema de tipo estático nominal ou um sistema dinâmico baseado em metadados de tempo de execução e, portanto, poucas pessoas se incomodam.

    
por 26.07.2011 / 21:46
fonte
1

Acredito que uma maneira de obter uma linguagem baseada em protótipo e tipificada estaticamente seria basear a linguagem em torno de modelos e conceitos.

Os conceitos já foram um recurso planejado para o C ++ 0x. Código genérico em modelos C ++ já está de facto "statically duck-typed". A idéia de Conceitos é ser capaz de dizer algumas coisas sobre membros requeridos e características de tipos, sem requerer ou implicar um modelo de herança de classe subjacente àquele relacionamento (porque ele tinha que trabalhar com código de modelo existente que já era "estaticamente pato digitado" ).

Em uma linguagem baseada em modelos e conceitos, seriam os Conceitos baseados em protótipos, e os Modelos o livrariam de qualquer modelo de classe que pudesse ou não ser usado para implementar os tipos de valores.

Além dos truques de usar a compilação por etapas para permitir que a linguagem seja sua própria linguagem, essas derivações prototípicas dos Conceitos seriam necessariamente imutáveis depois de criadas. No entanto, a objeção de que isso não é baseado em protótipos é um arenque vermelho. Seria simplesmente uma linguagem funcional. Uma linguagem de protótipo dinâmico que também é funcional pelo menos foi tentada .

    
por 17.07.2012 / 22:11
fonte