Esta alegação de Aleks Bromfield afirma:
Quase todos os idiomas com um sistema de tipos estáticos também possuem um sistema de tipos dinâmicos. Além de C, não consigo pensar em uma exceção
Esta é uma reivindicação válida? Entendo que, com as classes Reflection ou Loading em tempo de execução, o Java fica um pouco assim - mas essa ideia de 'digitação gradual' pode ser estendida a um grande número de linguagens?
languages
dynamic-typing
static-typing
Hawkeye
fonte
fonte
Respostas:
Tweeter original aqui. :)
Primeiro de tudo, estou um pouco divertido / chocado que meu tweet esteja sendo levado tão a sério! Se eu soubesse que isso seria amplamente divulgado, eu teria passado mais de 30 segundos escrevendo!
Thiago Silva está correto ao apontar que "estático" e "dinâmico" descrevem com mais precisão a verificação de tipos , em vez de sistemas de tipos . De fato, também não é preciso dizer que um idioma é digitado estaticamente ou dinamicamente. Em vez disso, uma linguagem possui um sistema de tipos, e uma implementação dessa linguagem pode impor o sistema de tipos usando verificação estática ou dinâmica, ou ambas, ou nenhuma das duas (embora isso não seja uma implementação de linguagem muito atraente!).
Por acaso, existem certos sistemas de tipos (ou recursos de sistemas de tipos) que são mais passíveis de verificação estática e existem certos sistemas de tipos (ou recursos de sistemas de tipos) que são mais passíveis de verificação dinâmica. Por exemplo, se seu idioma permitir que você especifique no texto de um programa que um valor específico sempre deve ser uma matriz de números inteiros, é razoavelmente simples escrever um verificador estático para verificar essa propriedade. Por outro lado, se o seu idioma tiver subtipagem e se permitir downcasting, é razoavelmente simples verificar a validade de um downcast em tempo de execução, mas extremamente difícil fazê-lo em tempo de compilação.
O que realmente quis dizer com meu tweet é simplesmente que a grande maioria das implementações de idiomas realiza alguma verificação dinâmica de tipo. Ou, equivalente, a grande maioria dos idiomas possui alguns recursos que são difíceis (se não impossíveis) de verificar estaticamente. Downcasting é um exemplo. Outros exemplos incluem estouro aritmético, verificação de limites de matriz e verificação nula. Alguns deles podem ser verificados estaticamente em algumas circunstâncias, mas, em geral, seria difícil encontrar uma implementação de idioma que não faça nenhuma verificação no tempo de execução.
Isso não é uma coisa ruim. É apenas uma observação de que existem muitas propriedades interessantes que gostaríamos que nossos idiomas aplicassem e que realmente não sabemos como verificar estaticamente. E é um lembrete de que distinções como "tipos estáticos" versus "tipos dinâmicos" não são tão claras quanto algumas pessoas querem que você acredite. :)
Uma observação final: os termos "forte" e "fraco" não são realmente usados na comunidade de pesquisa em linguagem de programação e não têm um significado consistente. Em geral, descobri que quando alguém diz que um idioma tem "digitação forte" e outro idioma tem "digitação fraca", eles estão realmente dizendo que seu idioma favorito (aquele com "digitação forte") os impede de cometer algum erro que o outro idioma (aquele com "digitação fraca") não - ou, inversamente, que seu idioma favorito (aquele com "digitação fraca") permita que eles façam algo interessante que o outro idioma (o um com "digitação forte") não.
fonte
Bem, sim. Você pode ter bolsas de propriedades em qualquer idioma digitado estaticamente. A sintaxe será terrível e, ao mesmo tempo, você obterá todas as desvantagens do sistema digitado dinamicamente. Portanto, não há realmente nenhuma vantagem, a menos que o compilador permita que você use uma sintaxe melhor, algo como o C #
dynamic
está fazendo.Além disso, você também pode fazer isso com facilidade em C.
Em reação a outras respostas: acho que as pessoas estão confundindo digitação estática / dinâmica com digitação forte / fraca. A digitação dinâmica é sobre ser capaz de alterar a estrutura dos dados em tempo de execução e o código é capaz de usar dados que se encaixam apenas no que o código precisa. Isso se chama Duck Typing .
Mencionar a reflexão não é contar a história toda, porque a reflexão não permite alterar a estrutura de dados existente. Você não pode adicionar um novo campo a uma classe ou estrutura em C, C ++, Java ou C #. Em linguagens dinâmicas, a adição de novos campos ou atributos às classes existentes não é apenas possível, mas também bastante comum.
Por exemplo, veja o Cython , o compilador Python-para-C. Ele cria código C estático, mas o sistema de tipos ainda mantém sua natureza dinâmica. C é uma linguagem de tipo estaticamente, mas é capaz de suportar a digitação dinâmica do Python.
fonte
ExpandoObject
, embora seja um processo de aceitação, muito diferente do JavaScript ou Ruby. Ainda assim, você fez uma observação muito importante: a digitação com patos (o que 99% dos desenvolvedores realmente querem dizer quando dizem "digitados dinamicamente") e reflexão não são as mesmas coisas.True
para dizer "esse objeto maluco é uma instância da classe que estou definindo"). OCaml tem esse recurso, tanto quanto eu entendo, mas eu realmente não sei.Linguagens dinâmicas são linguagens estáticas . O que é comumente chamado de "digitação dinâmica" é realmente um caso especial de digitação estática - o caso em que você se restringiu a ter apenas um tipo. Como um experimento mental, imagine escrever um programa em Java ou C # usando apenas
Object
variáveis / campos / parâmetros e fazer a conversão imediatamente antes de chamar qualquer método. Seria mais preciso chamar linguagens como Python ou Javascript "unificadas". (Essa alegação provavelmente confundirá / incomodará muitas pessoas, considerando que um programa Java ou C # usaria muitos subtipos, mas isso ocorre porque a linguagem OOP média confunde tipos e classes. Leia a postagem do blog para obter mais detalhes.)Observe que mesmo C possui digitação "dinâmica" - você pode converter qualquer ponteiro para um ponteiro
void
(e se a memória me servirchar
) e voltar. E observe também que não há verificação de tempo de execução lá; se você errar, aproveite seu comportamento indefinido!fonte
String foo = (String) bar
que não significa quebar
é de fato aString
. Você só pode saber isso em tempo de execução, então não vejo como o elenco é feito "estaticamente".dynamic
objeto para fazer isso. Se você tentar adicionar uma propriedade a umobject
... bem, não poderá.A diferença entre a digitação estática e a dinâmica é quando o tipo de um valor é verificado: tempo de compilação versus tempo de execução. Nas linguagens em que os valores carregam seu tipo com eles (por exemplo, objetos Java), você sempre pode recorrer à digitação dinâmica, mesmo quando a linguagem realmente prefere a digitação estática. Aqui está um exemplo em Java, com um método digitado dinamicamente:
Observe como o tipo de cada item é verificado no tempo de execução. O método equivalente estaticamente digitado é:
Em C, valores (e especificamente ponteiros) não retêm seu tipo durante o tempo de execução - todo ponteiro é equivalente a
void *
. Em vez disso, variáveis e expressões têm um tipo. Para obter uma digitação dinâmica, você deve carregar as informações de tipo (por exemplo, como um campo em uma estrutura).fonte
frobnicate
método aqui sem primeiro conhecerSpecificType
.dynamic
palavra - chave). Igualar estático ao tempo de compilação e dinâmico ao tempo de execução principalmente apenas atrapalha as águas.[1,2].Add([3,4])
produzir[1,2,3,4]
,[1,2,[3,4]]
ou[4,6]
?Add
método na matriz que aceite uma matriz porque esse método seria ambíguo. A digitação com patos não o dispensa de escrever tipos e funções compreensíveis.A digitação estática versus dinâmica refere-se basicamente a como os tipos são verificados. A digitação estática significa que a verificação dos tipos de várias variáveis ou expressões é verificada com base no código real (geralmente pelo compilador), enquanto em um sistema de tipo dinâmico essa verificação é realizada apenas em tempo de execução, pelo ambiente de tempo de execução.
O que eu acredito que o texto está se referindo é que, mesmo que os tipos sejam realmente verificados estaticamente, eles também são verificados em tempo de execução, ou seja, dinamicamente. Você mencionou corretamente o Java Reflection; a reflexão ocorre apenas no tempo de execução e o Java Runtime Environment (JVM) realmente executa a verificação de tipo quando a reflexão é usada, o que basicamente significa a verificação dinâmica de tipo.
fonte
A exceção está errada: C também possui um importante sistema de tipos dinâmicos. Simplesmente não verifica ("C é fortemente tipado, fracamente verificado"). Por exemplo, tratar uma estrutura como um
double
(reinternpret_cast
estilo) gera comportamento indefinido - um erro de tipo dinâmico.fonte