Em um sistema digitado dinamicamente, os valores têm tipos em tempo de execução, mas variáveis e funções não. Em um sistema estaticamente digitado, variáveis e funções têm tipos conhecidos e verificados em tempo de compilação. Por exemplo, em Python xpode ser qualquer coisa ; em tempo de execução, se é 1um número e se é "foo", é uma string. Você só saberia qual tipo xestava em tempo de execução e poderia ser diferente cada vez que você executava o programa. Em uma linguagem como Java, você escreveria int xse xfosse um número e saberia em tempo de compilação que xsempre deve ser um int.
Os tipos "explícito" e "implícito" referem-se a sistemas de tipos estáticos . A característica definidora de um sistema estático é que os tipos são conhecidos em tempo de compilação, mas não necessariamente que precisam ser gravados. Em Java, os tipos são explícitos - você precisa escrevê-los. Portanto, em Java, um método pode ser algo como:
public int foo(String bar, Object baz) { ... }
Os tipos são conhecidos no tempo de compilação (estático) e gravados (explícitos). No entanto, também existem idiomas que não o obrigam a escrever o tipo. Eles podem inferir o tipo de uma função do seu corpo e como ela é usada. Um exemplo seria OCaml, onde você pode escrever algo como:
let foo x = x + 1
Desde que você usou +, o OCaml pode descobrir que xdeve ser um inttodo por si só. Portanto, o tipo de foo( foo : int -> int) é conhecido em tempo de compilação, assim como o exemplo de Java. É totalmente estático. No entanto, como o compilador pode descobrir quais são os tipos por conta própria, você não precisa escrevê-los: eles estão implícitos.
Em resumo: se um sistema de tipos é explícito ou implícito é uma propriedade de sistemas estáticos . É uma questão completamente diferente de saber se um sistema de tipos é dinâmico ou estático.
Freqüentemente, você tem sistemas de tipos que às vezes são explícitos e às vezes implícitos.
Por exemplo, acredito que o C # permite inferir tipos usando a varpalavra - chave. Portanto, em vez de escrever int x = 10, você pode escrever var x = 10e o compilador descobre que xdeve ser um int. C ++ faz algo semelhante com auto. Esses sistemas geralmente são explícitos, mas têm alguma inferência.
Por outro lado, existem sistemas geralmente implícitos, mas às vezes forçam você a escrever uma assinatura de tipo. Haskell é um ótimo exemplo. Na maioria das vezes, Haskell pode inferir os tipos para você. No entanto, às vezes você pode escrever um código ambíguo show . read, onde Haskell não consegue descobrir os tipos por conta própria. Nesse caso, você seria forçado a especificar explicitamente o tipo de um showou de um read. Além disso, alguns recursos mais avançados do sistema de tipos (como o polimorfismo rank-n) tornam a inferência indecidível - ou seja, não é garantido que ele seja interrompido. Isso significa que o código que usa esse recurso geralmente precisa de assinaturas de tipo explícitas.