Esta pregunta puede sonar tonta, pero ¿por qué 0evalúa falsey cualquier otro valor [entero] truees la mayoría de los lenguajes de programación?
Comparación de cadenas
Dado 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? Puede haberlo, pero no ninguno Solía: ¿dónde se 0evalúa truey todos los demás valores [enteros] false? Ese comentario puede parecer aleatorio, pero tengo algunos ejemplos en los que puede haber sido una buena idea. En primer lugar, tomemos el ejemplo de la comparación de tres vías de cadenas, tomaré C strcmpcomo ejemplo: cualquier programador que intente C como su primer lenguaje puede verse tentado a escribir el siguiente código:
if (strcmp(str1, str2)) { // Do something... }
Como los strcmpretornos 0que se evalúan falsecuando las cadenas son iguales, lo que el programador principiante intentó hacer falla miserablemente y generalmente no comprende por qué al principio. En cambio, si hubiera 0evaluado trueesta función, podría haberse utilizado en su expresión más simple, la anterior, al comparar la igualdad, y las comprobaciones adecuadas -1y 1se habrían realizado solo cuando fuera necesario. Hubiéramos considerado el tipo de retorno como bool(en nuestra opinión, quiero decir) la mayor parte del tiempo.
Además, vamos a introducir un nuevo tipo sign, que solo toma valores -1, 0y 1. Eso puede ser bastante útil. Imagine que hay un operador de nave espacial en C ++ y lo queremos std::string(bueno, ya existe la comparefunción, pero el operador de nave espacial es más divertido). La declaración actualmente sería la siguiente:
sign operator<=>(const std::string& lhs, const std::string& rhs);
Si hubiera 0sido evaluado true, el operador de la nave espacial ni siquiera existiría, y podríamos haber declarado de operator==esa manera:
sign operator==(const std::string& lhs, const std::string& rhs);
Esto 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 y al mismo tiempo poder 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 lenguajes antiguos donde no existe tal cosa (C por ejemplo). Si miramos la biblioteca estándar de C (y POSIX uno también), podemos ver con certeza que las funciones pueden regresar 0cuando tienen éxito y cualquier número entero de lo contrario. 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 nuevamente, 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 allí para resolver los muchos casos de no. Sin embargo, en todos los lenguajes de programación que conozco (excepto quizás algunos lenguajes esotéricos experimentales), que yesevalúa falseen una ifcondición, mientras que todos los nocasos evalúan 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, haber 0evaluado truey el resto falsehabría tenido mucho más sentido.
Conclusión
Mi conclusión es esencialmente mi pregunta original: ¿por qué diseñamos lenguajes donde 0está falsey los demás valores true, teniendo en cuenta mis pocos ejemplos anteriores y tal vez algunos más en los 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 apasionado que pareces ser al respecto. Originalmente hice esta pregunta por aburrimiento, pero como pareces tan apasionado, decidí ir un poco más allá y preguntar sobre la razón detrás de la elección booleana para 0 y 1 en Math.SE :)
if true ; then ... ; fi, donde truees un comando que devuelve cero y esto le dice ifque se ejecute ....
booltipo pero las comparaciones / etc si las condiciones pueden tener cualquier valor de retorno.
strcmp()No es un buen ejemplo para verdadero o falso, ya que devuelve 3 valores diferentes. Y se sorprenderá cuando comience a usar un shell, donde 0 significa verdadero y cualquier otra cosa significa falso.