Esta pregunta puede parecer estúpida, pero ¿por qué 0
evalúa a false
y cualquier otro valor [entero] a true
es la mayoría de los lenguajes de programación?
Comparación de cadenas
Ya que la pregunta parece demasiado simple, me explicaré un poco más: en primer lugar, puede parecer evidente para cualquier programador, pero ¿por qué no habría un lenguaje de programación? pero no he usado ninguno, donde 0
se evalúa como true
y todos los demás valores [enteros] a false
? Esa observación puede parecer aleatoria, pero tengo algunos ejemplos en los que puede haber sido una buena idea. En primer lugar, tomemos el ejemplo de las cadenas de tres vías de comparación, tomaré el ejemplo de strcmp
de C: cualquier programador que pruebe C como su primer idioma puede tener la tentación de escribir el siguiente código:
if (strcmp(str1, str2)) { // Do something... }
Dado que strcmp
devuelve 0
, que se evalúa como false
cuando las cadenas son iguales, lo que el programador principiante intentó hacer falló miserablemente y generalmente no entiende por qué al principio. Si 0
hubiera sido evaluado como true
, esta función podría haberse usado en su expresión más simple, la anterior, al comparar la igualdad, y las verificaciones adecuadas de -1
y 1
se habrían realizado solo cuando necesario. Habríamos considerado el tipo de retorno como bool
(en nuestra opinión, me refiero) la mayor parte del tiempo.
Además, introduzcamos un nuevo tipo, sign
, que solo toma los valores -1
, 0
y 1
. Eso puede ser bastante útil. Imagina que hay un operador de la nave espacial en C ++ y lo queremos para std::string
(bueno, ya existe compare
función, pero el operador de la nave espacial es más divertido). La declaración sería actualmente la siguiente:
sign operator<=>(const std::string& lhs, const std::string& rhs);
Si 0
se hubiera evaluado como true
, el operador de la nave espacial ni siquiera existiría, y podríamos haber declarado operator==
de esa manera:
sign operator==(const std::string& lhs, const std::string& rhs);
Este operator==
habría manejado la comparación de tres vías a la vez, y aún podría usarse para realizar la siguiente verificación mientras aún se puede verificar qué cadena es lexicográficamente superior a la otra cuando sea necesario:
if (str1 == str2) { // Do something... }
Manejo de errores antiguos
Ahora tenemos excepciones, por lo que esta parte solo se aplica a los idiomas antiguos donde no existe tal cosa (por ejemplo, C). Si nos fijamos en la biblioteca estándar de C (y POSIX también), podemos ver con seguridad que muchas de las funciones devuelven 0
cuando tienen éxito y, de lo contrario, cualquier número entero. Lamentablemente he visto a algunas personas hacer este tipo de cosas:
#define TRUE 0
// ...
if (some_function() == TRUE)
{
// Here, TRUE would mean success...
// Do something
}
Si pensamos en cómo pensamos en la programación, a menudo tenemos el siguiente patrón de razonamiento:
Do something
Did it work?
Yes ->
That's ok, one case to handle
No ->
Why? Many cases to handle
Si lo pensamos de nuevo, tendría sentido poner el único valor neutral, 0
, a yes
(y así es como funcionan las funciones de C), mientras que todos los demás valores pueden estar ahí para resolver el problema. Muchos casos de no
. Sin embargo, en todos los lenguajes de programación que conozco (excepto quizás algunos lenguajes esotéricos experimentales), yes
se evalúa como false
en una condición if
, mientras que todos los casos no
se evalúan como true
. Hay muchas situaciones en las que "funciona" representa un caso, mientras que "no funciona" representa muchas causas probables. Si lo pensamos de esa manera, tener 0
evalúa a true
y el resto a false
hubiera tenido mucho más sentido.
Conclusión
Mi conclusión es esencialmente mi pregunta original: ¿por qué diseñamos idiomas donde 0
es false
y los otros valores son true
, teniendo en cuenta mis pocos ejemplos anteriores y tal vez algunos más que no pensé?
Seguimiento: Es bueno ver que hay muchas respuestas con muchas ideas y tantas razones posibles para que sea así. Me encanta lo apasionada que pareces al respecto. Originalmente hice esta pregunta por aburrimiento, pero ya que pareces muy apasionado, decidí ir un poco más lejos y preguntar sobre la justificación detrás de la opción booleana para 0 y 1 en Math.SE :)