Esta pregunta puede sonar tonta, pero ¿por qué 0
evalúa false
y cualquier otro valor [entero] true
es 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 0
evalúa true
y 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 strcmp
como 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 strcmp
retornos 0
que se evalúan false
cuando 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 0
evaluado true
esta función, podría haberse utilizado en su expresión más simple, la anterior, al comparar la igualdad, y las comprobaciones adecuadas -1
y 1
se 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
, 0
y 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 compare
funció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 0
sido 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 0
cuando 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 yes
evalúa false
en una if
condición, mientras que todos los no
casos 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 0
evaluado true
y el resto false
habría tenido mucho más sentido.
Conclusión
Mi conclusión es esencialmente mi pregunta original: ¿por qué diseñamos lenguajes donde 0
está false
y 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 true
es un comando que devuelve cero y esto le dice if
que se ejecute ...
.
bool
tipo 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.