Essa pergunta pode parecer burra, mas por que 0
avalia false
e qualquer outro valor [inteiro] para true
é a maioria das linguagens de programação?
Comparação de sequências
Como a pergunta parece um pouco simples demais, vou me explicar um pouco mais: em primeiro lugar, pode parecer evidente para qualquer programador, mas por que não haveria uma linguagem de programação - pode realmente haver, mas não usei nenhum - onde 0
avalia para true
e todos os outros valores [integer] para false
? Essa observação pode parecer aleatória, mas tenho alguns exemplos em que pode ter sido uma boa ideia. Antes de mais nada, vamos pegar o exemplo da comparação tridimensional de strings, vou usar o strcmp
de C como exemplo: qualquer programador que tente C como sua primeira linguagem pode ser tentado a escrever o seguinte código:
if (strcmp(str1, str2)) { // Do something... }
Como strcmp
retorna 0
, que é avaliado como false
quando as strings são iguais, o que o programador iniciante tentou fazer falhar miseravelmente e ele geralmente não entende por que a princípio. Tinha 0
avaliado como true
, essa função poderia ter sido usada em sua expressão mais simples - a acima - ao comparar por igualdade, e as verificações adequadas para -1
e 1
teriam sido feitas somente quando necessário. Teríamos considerado o tipo de retorno como bool
(em nossas mentes, quero dizer) na maioria das vezes.
Além disso, vamos introduzir um novo tipo, sign
, que apenas recebe valores -1
, 0
e 1
. Isso pode ser muito útil. Imagine que há um operador de espaçonave em C ++ e nós queremos isso para std::string
(bem, já existe o compare
função, mas operador de espaçonave é mais divertido). A declaração seria atualmente a seguinte:
sign operator<=>(const std::string& lhs, const std::string& rhs);
O 0
foi avaliado como true
, o operador da espaçonave nem existiria e poderíamos ter declarado operator==
dessa maneira:
sign operator==(const std::string& lhs, const std::string& rhs);
Este operator==
teria lidado com a comparação de três vias de uma só vez, e ainda poderia ser usado para realizar a seguinte verificação enquanto ainda seria capaz de verificar qual cadeia é lexicograficamente superior à outra quando necessário:
if (str1 == str2) { // Do something... }
Erros antigos que manipulam
Agora temos exceções, portanto, essa parte só se aplica aos idiomas antigos em que não existe tal coisa (C, por exemplo). Se olharmos para a biblioteca padrão do C (e também para o POSIX), podemos ver com certeza que as funções maaaaany retornam 0
quando bem sucedidas e qualquer número inteiro caso contrário. Eu infelizmente vi algumas pessoas fazerem esse tipo de coisa:
#define TRUE 0
// ...
if (some_function() == TRUE)
{
// Here, TRUE would mean success...
// Do something
}
Se pensarmos em como pensamos na programação, geralmente temos o seguinte padrão de raciocínio:
Do something
Did it work?
Yes ->
That's ok, one case to handle
No ->
Why? Many cases to handle
Se pensarmos sobre isso novamente, faria sentido colocar o único valor neutro, 0
, em yes
(e é assim que funcionam as funções de C), enquanto todos os outros valores podem estar lá para resolver o problema. muitos casos do no
. No entanto, em todas as linguagens de programação que eu conheço (exceto talvez algumas linguagens esotéricas experimentais), que yes
avalia false
em uma condição if
, enquanto todos os no
casos são avaliados como true
. Há muitas situações em que "funciona" representa um caso enquanto "não funciona" representa muitas causas prováveis. Se pensarmos dessa forma, ter 0
avaliado em true
e o restante em false
teria feito muito mais sentido.
Conclusão
Minha conclusão é essencialmente a minha pergunta original: por que projetamos idiomas em que 0
é false
e os outros valores são true
, levando em conta meus poucos exemplos acima e talvez um pouco mais eu não pensei?
Acompanhamento: É bom ver que há muitas respostas com muitas ideias e tantas possíveis razões para que seja assim. Eu amo o quão apaixonado você parece ser sobre isso. Eu originalmente fiz essa pergunta de tédio, mas desde que você parece tão apaixonada, eu decidi ir um pouco mais longe e perguntar sobre o raciocínio por trás da escolha booleana para 0 e 1 em Math.SE:)