Linguagens Alternativas
A linguagem JavaScript pode ser considerada a mais importante e a mais usada no desenvolvimento do lado cliente (código que é executado pelos navegadores (browsers) de aplicações para web. Ainda assim, ela não está livre de críticas, especialmente por algumas características incomuns.
Suponha que um desenvolvedor queira definir uma função que calcule a média de dois números. Uma solução razoável seria:
// calcula a média artimética simples de dois números
function media(n1, n2) {
return (n1 + n2) / 2;
}
Invocando a função media(3,4)
produz o resultado 3.5
. Mas o que acontece nos seguintes casos:
let a = media(true, 5);
let b = media(false, true);
let c = media('uva', 8);
let d = media('banana', 'melancia');
let e = media(3, 4, 5);
let f = media(4);
Contrariamente ao que acontece em muitas linguagens, todos os 6 casos são perfeitamente válidos em JavaScript. A execução da função media
não gera erros de execução.
Os valores das 6 variáveis são:
- a vale o número 3 porque o valor lógico
true
é convertido para o número1
. - b vale o número 0.5 porque os valores lógicos
false
etrue
são convertidos para os números0
e1
. - c vale o número NaN porque dividir uma
string
(no caso'uva8'
por um número resulta emNaN
. - d vale o número NaN porque, como em
c
, dividir a string'bananamelancia'
por um número resulta emNaN
. - e vale o número 7 porque o terceiro número (
5
) é avaliado (vale 5) e depois é simplesmente ignorado. - f vale NaN porque o valor do segundo parâmetro vale
undefined
e a soma de um número com 'undefined' vale 'NaN'
Em todos os 6 casos a função media
retornou um número, que era o tipo esperado. Se for experiente em JavaScript, o desenvolvedor não fica surpreso com os resultados obtidos pois ele sabe que as conversões acontecem. Afinal, esta é uma característica de JavaScript.
O problema está no fato de que raramente os 6 casos expressam a intenção do desenvolvedor. A função media
, pela forma como foi definida e pelo seu propósito, pressupõe que seja invocada com exatamente dois argumentos do tipo número. É muito mais provável que os 6 casos representem bugs (falhas) de programação.
A falha neste caso não está no algoritmo utilizado na implementação da função media
. A falha está na forma como a função está sendo chamada. Em uma aplicação grande ela pode estar sendo chamada muitas e muitas vezes.
A melhor forma para detectar usos incorretos da função media
é definindo testes unitários que avaliam os códigos em que media
aparece. Se alguns testes falharem o motivo pode ser "invocação não prevista para a função media
".
O lado negativo da solução acima é que é um processo lento (criar testes apropriados) e sempre há a possibilidade de esquecer de testar alguma coisa.
Paradoxalmente, as características que tornam JavaScript tão flexível são as mesmas que dificultam o desenvolvimento de aplicações corretas:
- tipagem dinâmica (uma variável pode armazenar dados de qualquer tipo a qualquer momento).
- conversões impícitas de tipos (como
true
valer1
efalse
valer0
). - o número de parâmetros definidos para uma função não impede que ela seja invocada com menos ou com mais argumentos (como no caso das variáveis
e
ef
.
Erros "bobos" como media(n1 + n2)
podem demorar horas até serem descobertos.
As questões acima incentivam o desenvolvimento de linguagens alternativas. Ao mesmo tempo, não é uma abordagem fácil simplesmente dizer "abandonem JavaScript e utilizem a linguagem x
". Há todo um ecosistema em torno de JavaScript.
Uma abordagem que tem feito bastante sucesso é criar linguagens de programação que compilam para JavaScript. Assim o desenvolvimento é feito nestas linguagens e a execução é feita em JavaScript. Além disso a integração com bibliotecas JavaScript é simples de ser feita. Dois exemplos de linguagem de programação dentro desta abordagem são *TypeScript e Elm. Elas, no entanto, atingem o mesmo objetivo por caminhos completamente diferentes.
Leitura Sugerida |
---|
Enganos clássicos em JavaScript |