Eu já havia determinado que assuntos de programação seriam publicados no
Kodumaro, deixando
este blog pro meu blá-blá-blá habitual.
No entanto surgiu um assunto sobre programação que é, ao mesmo tempo, reclamação minha.
Sei que programadores de linguagens de tipagem fraca e dinâmica e programadores de linguagens de tipagem forte e estática têm dificuldade em diferenciar tipagem fraca de dinâmica e tipagem forte de estática, porém isso está chegando a um extremo de eu ler essa confusão em livros didáticos!
Chega dessa confusão, vou tentar explicar um pouco.
Resistência a coerção
Toda linguagem de programação possui tipos de dados e coerção ou conversão entre tipos. Quanto mais variados e bem definidos os tipos da linguagem, mais difícil é a coerção entre eles e diz-se que a linguagem é mais forte. Muitas linguagens de tipagem forte chegam a requerer um coerção explícita, chamada
typecasting.
Linguagens com poucos tipos ou cuja diferença entre os tipos seja fraca, são chamadas de tipagem fraca.
Por exemplo, duas linguagens de tipagem fraca são
Javascript e
Lua:
value = 12
value = value + "2"
A sentença acima é válida tanto em Javascript quanto em Lua e, nas duas, o valor final da variável
value
é 14.
Isso acontece porque, como o primeiro parâmetro da soma era um número inteiro, o segundo parâmetro (a
string "2"
) foi implicitamente convertida para seu equivalente numérico.
Esse tipo de mágica pode gerar
problemas desagradáveis e erros difíceis de serem depurados, mas é uma abordagem válida se o programador decidir conviver com isso.
Já linguagens de tipagem forte, como
Python e
Java, geram exceções caso você tente usar um objeto como se fosse de um tipo diferente dele:
>>> value = 12
>>> value = value + "2"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'
Como você pode ver, Python reclama imediatamente do tipo. É preciso executar uma coerção explícita.
Quem determina o tipo?
Outra questão é, havendo tipos definidos, quem determina o tipo.
Se o tipo de um dado é determinado por seu
container, a variável que o referencia, a tipagem é dita estática. Por exemplo, Java e
C são linguagens de tipagem estática.
Já quando o próprio dado já possui seu tipo auto-contido, independente de quem o referencie, a tipagem é chamada dinâmica. Python e
Erlang possuem tipagem dinâmica.
Agora, repare uma coisa: uma linguagem ser forte ou fraca não tem nada a ver com ela ser estática ou dinâmica. Vimos diversos exemplos:
- Lua e Javascript possuem tipagem fraca e dinâmica.
- Python e Erlang possuem tipagem forte e dinâmica.
- Java possui tipagem forte e estática.
- C possui tipagem fraca e estática.
Sim! A tipagem de C é fraca e estática, ao contrário do que muita gente pensa. A coerção entre tipos de C é muito simples, basta você usar ponteiros de tipos diferentes para referenciar o mesmo valor – mesmo que o resultado não seja o esperado por quem programa em outras linguagens de tipagem fraca:
char var_1[] = "A";
unsigned char *var_2;
var_2 = var_1;
O valor de *var_1
será a string "A"
, enquanto o valor de *var_2
(ponteiro que aponta para o mesmo dado na memória) será 65. O tipo é atribuído pelo ponteiro/variável.
Portanto, ao contrário do que muita gente prega, uma linguagem pode ter tipagem estática e fraca sim.
[update 2013-10-16]
O valor de *var_2
ou var_2[0]
será 65, mas o valor de var_2[1]
será 0.
Isso ocorre porque em C strings são listas de caracteres terminadas com nulo (\000
).
[/update]
Creio que isso possa ter esclarecido algumas coisas que as pessoas repetem por aí à moda
Goebbels.
[]’s
Cacilhας, La Batalema