Pergunta

Vejo esses termos espalhados por toda parte na programação e tenho uma vaga noção do que eles significam.Uma pesquisa me mostra que, de fato, essas coisas foram feitas em todo o estouro de pilha.Pelo que sei, a digitação estática/dinâmica em idiomas é sutilmente diferente da digitação forte/fraca, mas qual é essa diferença me escapa.Fontes diferentes parecem usar significados diferentes ou até mesmo usar os termos de forma intercambiável.Não consigo encontrar algum lugar que fale sobre ambos e realmente explique a diferença.O que seria bom seria se alguém pudesse explicar isso claramente aqui para mim e para o resto do mundo.

Foi útil?

Solução

  • Digitação estática/dinâmica é sobre quando As informações de tipo são adquiridas (no horário de compilação ou em tempo de execução)

  • Digitação forte/fraca é sobre Quão estritamente Os tipos são distinguidos (por exemplo, se o idioma tenta fazer uma conversão implícita de strings em números).

Veja o wiki-página Para informações mais detalhadas.

Outras dicas

Você descobriu um ponto fraco na terminologia que os amadores usam para falar sobre linguagens de programação.Não use os termos digitação "forte" e "fraca", porque eles não têm um significado técnico universalmente acordado.Por contraste, digitação estática significa que os programas são verificado antes de ser executado, e um programa pode ser rejeitado antes de ser iniciado. Digitação dinâmica significa que os tipos de valores são verificados durante execução, e uma operação mal digitada pode fazer com que o programa pare ou sinalizar um erro em tempo de execução.A principal razão para a digitação estática é descartar programas que possam ter tais "erros de tipo dinâmico".

Digitação forte geralmente significa que existem sem lacunas no sistema de tipos, enquanto digitação fraca significa que o sistema de tipos pode ser subvertido (invalidando quaisquer garantias).Os termos são frequentemente usados ​​incorretamente para significar digitação estática e dinâmica.Para ver a diferença, pense em C:o tipo da linguagem é verificado em tempo de compilação (digitação estática), mas há muitas lacunas;você pode converter praticamente um valor de qualquer tipo para outro tipo do mesmo tamanho --- em particular, você pode converter tipos de ponteiro livremente.Pascal era uma linguagem que deveria ser fortemente tipada, mas notoriamente tinha uma lacuna imprevista:um registro variante sem tag.

As implementações de linguagens fortemente tipadas muitas vezes adquirem lacunas ao longo do tempo, geralmente para que parte do sistema de tempo de execução possa ser implementada na linguagem de alto nível.Por exemplo, Objective Caml tem uma função chamada Obj.magic que tem o efeito em tempo de execução de simplesmente retornar seu argumento, mas em tempo de compilação converte um valor de qualquer tipo em qualquer outro tipo.Meu exemplo favorito é Modula-3, cujos designers chamaram sua construção de conversão de tipo LOOPHOLE.

Dito isto, você não pode contar com duas pessoas usando as palavras “forte” e “fraco” exatamente da mesma maneira.Portanto, evite-os.

Simplesmente coloque desta maneira: em um linguagem estaticamente digitada o tipo é estático, ou seja, depois de definir uma variável para um tipo, você não pode alterá -la. Isso ocorre porque a digitação está associada à variável, e não ao valor a que se refere.

Por exemplo, em Java:

String str = "Hello";  //statically typed as string
str = 5;               //would throw an error since java is statically typed

Enquanto em a linguagem dinamicamente digitada o tipo é dinâmico, ou seja, depois de definir uma variável para um tipo, você pode alterá -lo. Isso ocorre porque a digitação está associada ao valor e não à variável.

Por exemplo, em Python:

str = "Hello" # it is a string
str = 5       # now it is an integer; perfectly OK

Por outro lado, o Digitação forte/fraca Em um idioma, está relacionado a conversões de tipo implícito (em parte da resposta de @Dario):

Por exemplo, em Python:

str = 5 + "hello" 
# would throw an error since it does not want to cast one type to the other implicitly. 

Considerando que no PHP:

$str = 5 + "hello"; // equals 5 because "hello" is implicitly casted to 0 
// PHP is weakly typed, thus is a very forgiving language.

A digitação estática permite a verificação da correção do tipo em tempo de compilação. Os idiomas estaticamente digitados são geralmente compilados e os idiomas tipados dinamicamente são interpretados. Portanto, idiomas dinâmicos digitados podem verificar a digitação no tempo de execução.

A digitação fraca significa que o tipo de um objeto pode mudar dependendo do contexto.Por exemplo, em uma linguagem de digitação fraca, a string "123" pode ser tratada como o número 123 se você adicionar outro número a ela.Exemplos de linguagens com digitação fraca são bash, awk e PHP.

Outro tipo de linguagem de tipo fraco é C, onde os dados em um endereço de memória podem ser tratados como um tipo diferente por conversão.

Em uma linguagem fortemente tipada, o tipo de objeto não muda - um int é sempre um int e tentar usá-lo como uma string resultará em erro.Tanto Java quanto Python são fortemente tipados.

A diferença entre digitação dinâmica e estática é quando as regras de tipo são aplicadas.Em uma linguagem de tipo estaticamente, o tipo de cada variável e parâmetro deve ser declarado na fonte e aplicado em tempo de compilação.Em uma linguagem de tipo dinâmico, os tipos só são verificados quando são usados ​​em tempo de execução.Portanto, Java é digitado estaticamente e Python é digitado dinamicamente.

No entanto, os limites podem ser um pouco confusos às vezes.Por exemplo, embora Java seja digitado estaticamente, toda vez que você usa reflexão ou conversão (por exemplo,ao usar contêineres de objetos), você está adiando a verificação de tipo para o tempo de execução.

Da mesma forma, as linguagens mais fortemente tipadas ainda serão convertidas automaticamente entre números inteiros e flutuantes (e em algumas linguagens, BigInts de precisão bitrária).

Hoje pesquisando sobre esse assunto, me deparei com este ótimo artigo http://blogs.perl.org/users/ovid/2010/08/what-to-know-fefore-debating-type-systems.html Isso esclareceu muitas coisas para mim e eu pensei que isso poderia adicionar a algumas das ótimas respostas acima.

Digitação forte e fraca:

Provavelmente, os sistemas de tipo de maneira mais comum são classificados é "forte" ou "fraca". Isso é lamentável, já que essas palavras quase não têm significado. É, em uma extensão limitada, possível comparar dois idiomas com sistemas de tipo muito semelhante e designar um como tendo o mais forte desses dois sistemas. Além disso, as palavras não significam nada.

Tipos estáticos e dinâmicos

Esta é quase a única classificação comum de sistemas de tipo que têm significado real. De fato, seu significado é frequentemente subestimado [...] sistemas de tipos dinâmicos e estáticos são duas coisas completamente diferentes, cujos objetivos se sobrepõem parcialmente.

Um sistema de tipo estático é um mecanismo pelo qual um compilador examina o código -fonte e atribui rótulos (chamados "tipos") a pedaços da sintaxe e depois os usa para inferir algo sobre o comportamento do programa. Um sistema de tipo dinâmico é um mecanismo pelo qual um compilador gera código para acompanhar o tipo de dados (coincidentemente, também chamado de "tipo") usado pelo programa. O uso da mesma palavra "tipo" em cada um desses dois sistemas, é claro, não é realmente totalmente coincidência; No entanto, é melhor entender como tendo uma espécie de significado histórico fraco. Grande confusão resulta da tentativa de encontrar uma visão de mundo na qual "tipo" realmente significa a mesma coisa nos dois sistemas. Não.

Tipos explícitos/implícitos:

Quando esses termos são usados, eles se referem à medida em que um compilador raciocinará sobre os tipos estáticos de partes de um programa. Todas as linguagens de programação têm alguma forma de raciocínio sobre tipos. Alguns têm mais do que outros. ML e Haskell têm tipos implícitos, pois não são necessários (ou muito poucos, dependendo do tipo de idioma e extensões em uso) são necessárias declarações. Java e ADA têm tipos muito explícitos, e um está constantemente declarando os tipos de coisas. Todos os itens acima têm (relativamente, em comparação com C e C ++, por exemplo) sistemas de tipo estático fortes.

Do Scott Pragmática da Linguagem de Programação, 3ª edição página 291, temos

A verificação do tipo é o processo de garantir que um programa obedece às regras de compatibilidade do tipo de idioma.Uma violação das regras é conhecida como um confronto do tipo.Diz-se que uma linguagem é fortemente digitado Se proibir, de uma maneira que a implementação do idioma possa aplicar, a aplicação de qualquer operação a qualquer objeto que não seja destinado a apoiar essa operação.Diz-se que uma linguagem é digitado estaticamente Se for fortemente digitado e a verificação do tipo poderá ser realizada no momento da compilação.No sentido mais estrito do termo, poucos idiomas são estaticamente digitados.Na prática, o termo geralmente é aplicado a idiomas nos quais a maioria das verificações de tipos pode ser realizada no momento da compilação, e o restante pode ser realizado no tempo de execução.

Alguns exemplos:A ADA é fortemente digitada e, na maioria das vezes, digitados estaticamente (certas restrições de tipo devem ser verificadas no tempo de execução).Uma implementação Pascal também pode fazer a maior parte de seu tipo de verificação no momento da compilação, embora o idioma não seja bem digitado:Os registros variantes não marcados (a serem discutidos na Seção 7.3.4) são sua única brecha.O C89 é significativamente mais fortemente digitado do que seus dialetos antecessores, mas ainda assim significativamente menos fortemente digitado que Pascal.Suas brechas incluem sindicatos, sub -rotinas com números variáveis ​​de parâmetros e a interoperabilidade de ponteiros e matrizes (a serem discutidos na Seção 7.7.1).As implementações de C raramente verificam qualquer coisa no tempo de execução.

A verificação do tipo dinâmico (em tempo de execução) é uma forma de ligação tardia e tende a ser encontrada em idiomas que atrasam outros problemas até o tempo de execução.Lisp e Smalltalk são digitados dinamicamente (embora fortemente).A maioria dos idiomas de script também é digitada dinamicamente;Alguns (por exemplo, Python e Ruby) são fortemente digitados.Os idiomas com escopo dinâmico são geralmente digitados dinamicamente (ou não digitados):Se o compilador não conseguir identificar o objeto ao qual um nome se refere, geralmente não poderá determinar o tipo do objeto.

Então, em termos simples, a digitação estática/dinâmica refere-se ao momento em que ocorre a verificação de tipo:tempo de compilação para digitação estática e tempo de execução para linguagens dinâmicas.Da mesma forma, a digitação forte/fraca refere-se ao quão agressiva uma linguagem é na aplicação de seu sistema de tipos.

Tentei traduzir a descrição de Scott em um belo diagrama, que postei abaixo.

The Static/Dynamic - Strong/Weak Typing Plane

Eu acho que os outros colegas fizeram um bom trabalho esp. explicando a diferença entre a digitação estática e dinâmica. Mas, no que diz respeito à digitação forte e fraca, deve -se dizer que existem diferentes entendimentos/visões.

Aqui dois exemplos:

  • Alguns dizem que Haskell é fortemente digitado, porque você não tem permissão para fazer algum Digite conversões.

  • Outros (por exemplo, a visão de Dario) dizem que um idioma que permite converter implicitamente de string em número de propósito é fracamente digitado, mas mesmo outros chamam isso de apenas digitação de pato.

Ambas as declarações destacam não os extremos opostos de um sistema de tipo, mas aspectos completamente diferentes. Então, junto -me à visão do Sr. Ramsey para não usar os termos "fortes" e "fracos" para distinguir entre os sistemas de tipo.

Linguagens de tipo estaticamente versus dinamicamente

  • Linguagens de tipo estaticamente são aquelas em que a verificação de tipo é feita em tempo de compilação, então isso também significa que em linguagens de tipo estaticamente cada variável tem um tipo e não muda ao longo do curso. Agora, em contraste, linguagens de tipo dinâmico são aquelas em que a verificação de tipo é feita em tempo de execução e não há verificação de tipo em tempo de compilação, então isso também significa que em linguagens de tipo dinâmico pode ou não haver um tipo associado a variáveis, e se um tipo estiver associado, então pode ser um tipo genérico como “var” em JS, que é válido tanto para uma string quanto para um número.
    • “Implementações de linguagens com verificação de tipo dinamicamente geralmente associam cada objeto de tempo de execução a uma tag de tipo (ou seja, uma referência a um tipo) contendo suas informações de tipo.Essas informações de tipo de tempo de execução (RTTI) também podem ser usadas para implementar despacho dinâmico, ligação tardia, downcasting, reflexão e recursos semelhantes.”
  • Mesmo que a linguagem seja digitada estaticamente, ela ainda pode ter algum recurso de digitação dinâmica, o que basicamente significa algum tipo de verificação de tipo em tempo de execução também.Isso é útil na conversão de tipos.
    • “Vários recursos úteis e comuns da linguagem de programação não podem ser verificados estaticamente, como downcasting.Assim, muitas linguagens terão verificação de tipo estática e dinâmica;o verificador de tipo estático verifica o que pode e as verificações dinâmicas verificam o resto.”
  • “Algumas linguagens permitem escrever códigos que não são seguros para o tipo.Por exemplo, em C, os programadores podem converter livremente um valor entre quaisquer dois tipos que tenham o mesmo tamanho.”
  • As vantagens das linguagens de tipo “estaticamente” são:
    • Como a maior parte da verificação de tipo é feita em tempo de compilação, o intérprete ou o tempo de execução podem rodar em velocidade total, sem se preocupar com os tipos.
    • Isso leva a um menor número de exceções de tempo de execução ou erros relacionados ao tipo, porque a maior parte da verificação de tipo é feita em tempo de compilação.
  • As vantagens das linguagens digitadas “dinamicamente” são:
    • Eles poderiam ajudar na prototipagem extremamente rápida, já que o desenvolvedor não precisa entender o sistema de tipos para que o desenvolvedor possa criar variáveis ​​e executá-las livremente, e isso leva a uma prototipagem muito rápida.
  • Lista de linguagens de tipagem estática e dinâmica:
    • Estatisticamente:
      • Java
      • C (C é uma linguagem de tipo estaticamente, mas de tipo menos “forte” em comparação com Java porque permite conversões mais implícitas)
      • C++
      • C#
    • Dinamicamente:
      • PERL
      • PHP
      • Pitão
      • JavaScript
      • Rubi
  • A verificação de tipo é um recurso de segurança importante. Suponha que não haja verificação de tipo e um método aceite um objeto do tipo “BankAccount” que possui um método chamado “creditAccount (BankAccountDetails)”, agora em tempo de execução se não houver verificação de tipo então posso passar um objeto meu classe que possui o mesmo método “creditAccount (BankAccountDetails)” e será executada, visto que estamos falando de linguagem orientada a objetos porque OOP suporta “polimorfismo” e aqui o que estamos discutindo nada mais é do que “polimorfismo”.Então, basicamente, uma linguagem orientada a objetos (o que basicamente significa que ela suporta “polimorfismo”) que não possui verificação de tipo forte pode levar a problemas de segurança.

Linguagens de digitação forte e fraca

  • Linguagens fortemente tipadas são aquelas nas quais conversões implícitas não são permitidas se houver perda de precisão.Por exemplo, em Java, você pode converter um “int para long” porque não há perda de precisão, mas não pode converter “implicitamente” um “long para int” porque haveria perda de precisão.Em contraste, em linguagens de tipo fraco, as conversões implícitas são permitidas mesmo que haja perda de precisão.
  • Acho que uma linguagem de tipo dinâmico também pode ser uma linguagem de tipo forte se “em tempo de execução” não permitir conversões implícitas nas quais haja perda de precisão.

Boas leituras adicionais

Linguagens de tipo estaticamente geralmente exigem que você declare os tipos de variáveis, que são então verificados em tempo de compilação para reduzir erros.A palavra "estático" em "digitado estaticamente" refere-se à "análise estática de código", que é o processo de examinar o código antes de executá-lo.Embora seja possível para uma linguagem de tipo estaticamente inferir o tipo da variável do lado direito de uma expressão ou de parâmetros reais, na prática a maioria das linguagens de tipo estaticamente exige que os tipos de variáveis ​​sejam declarados explicitamente.

Linguagens de tipo dinâmico geralmente não exigem declarações de variáveis ​​para terem tipos e inferem tipos de variáveis ​​com base no tipo calculado como resultado da avaliação do lado direito de cada instrução de atribuição ou dos parâmetros reais de uma chamada de função.Como a variável pode receber múltiplas atribuições ao longo de seu tempo de vida, seu tipo pode mudar com o tempo e é por isso que ela é chamada de "digitada dinamicamente".Além disso, o ambiente de tempo de execução precisa acompanhar o tipo atual de cada variável, de modo que o tipo esteja vinculado ao valor e não à declaração da variável.Isso pode ser considerado um sistema de informações de tipo de tempo de execução (RTTI).

Elementos de linguagens de tipagem estática e dinâmica podem ser combinados.Por exemplo, C# suporta variáveis ​​de tipo estático e dinâmico, e linguagens orientadas a objetos geralmente suportam downcasting da hierarquia de tipos.Linguagens de tipo estaticamente geralmente fornecem várias maneiras de ignorar a verificação de tipo, por exemplo, usando conversão, reflexão e invocação dinâmica.

Forte vs.A digitação fraca refere-se a um continuum de quanto a linguagem tenta evitar bugs devido ao uso de uma variável como se fosse um tipo, quando na verdade é outro tipo.Por exemplo, tanto C quanto Java são linguagens de tipo estaticamente; no entanto, Java usa verificação de tipo muito mais forte do que C.O código C a seguir pode ser compilado e executado e colocará um valor aleatório na variável b em tempo de execução, provavelmente causando um bug:

char *a = "123";
int b = (int)a;

O código Java equivalente produzirá um erro de compilação, o que geralmente é preferível:

String a = "123"
int b = (int)a;
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top