A veces tengo una función que debería devolver verdadero o falso. Pero a veces tres valores posibles tendrían más sentido.
En algunos idiomas, estos casos se manejarían con enteros o con excepciones.
Por ejemplo, desea controlar la edad de un usuario si es mayor de 18 años. Y tienes una función como esta.
if(user.isAdult(country_code)){
//Go On
}else{
// Block access or do nothing
}
Pero en algunos casos, dependiendo de cómo esté construida su aplicación, podría ver casos en los que el campo de cumpleaños está incompleto. Entonces esta función debería devolver algo indeterminado.
switch(user.isAdult()){
case true:
// go on
break;
case undetermined:
//Inform user birthday is incomplete
case false:
//Block access
}
Como dije, podemos manejar eso con Exceptions e Int, pero me parecería bastante sexy tener un verdadero, falso, indeterminado incrustado en el lenguaje en lugar de usar algunas constantes definidas en casa.
Respuestas:
Esto se puede manejar con enumeraciones, enteros, símbolos (por ejemplo, Lisp, Ruby), tipos anulables (use nulo como estado indeterminado), tipos de opciones (por ejemplo, ML) o alguna construcción similar, dependiendo de su idioma.
Entonces, si bien su ejemplo y razón son sólidos, no puedo ver que se encuentre en la lista de prioridades de las características del lenguaje a desarrollar.
fuente
null
. En C / C ++ puede devolver una enumeración.No he visto un caso en el que esto sea necesario. En el ejemplo que ha dado, si ese campo es necesario, debería haberse validado en otro lugar.
isAdult()
es inherentemente un método de dos estados: eres o no lo eres. No es necesario que haga nada más que devolver falso si encuentra datos que no puede manejar. Por ejemplo:fuente
.isAdult()
consultado al usuario mismo, si eso es realmente lo que desea, y eso funcionaría mejor.verdadero, falso, desconocido
si no talvez
en C # puede usar un bool anulable (puede retroceder con horror ahora)
en MS-SQL, puede usar un campo de bit anulable (ídem)
fuente
unknown
.En C ++, esto se puede manejar con un
bool
tipo sin retorno o lanzando una excepción. Si desea un tipo de retorno de tres valores, use unenum
. No es tan sexy, pero funciona, y lo que es más importante, puedes hacerlo sin estropear el idioma para el resto de nosotros.Tener
bool
tres valores causaría problemas. ¿Cómo se manejabool foo; ... if (foo)...
, suponiendo quefoo
pueda tener alguno de los tres valores? Hay ventajas en tenerbool
las variables de tal manera que, precisamente, uno de losfoo
y!foo
es verdad en todo momento. Ayuda a razonar sobre los programas.Vea lo que las personas hacen en el procesamiento numérico cuando posiblemente puedan obtener
NaN
valores. Es complicado. Prefiero no tener que pasar por eso para el procesamiento booleano ordinario.Si desea
.isAdult()
manejar información insuficiente, haga que lo haga internamente y luego devuelvatrue
ofalse
. De lo contrario, cada vez que lo use, debe verificar el código de retorno antes de hacer cualquier otra cosa, y encontrar una manera de manejarlo. Significaría que debe verificar los documentos para ver si una función realmente hizo lo que su nombre dice que hizo, y eso sería un desastre para la legibilidad.fuente
La idea es bastante útil. Hay todo un campo dedicado a lidiar con la incertidumbre llamado Fuzzy Logic .
Afortunadamente para nosotros los programadores, puede implementar lógica difusa con características de lenguaje estándar.
Por ejemplo, en el caso que proporcionó, la información incierta se puede determinar fácilmente preguntando al usuario. Entonces, una enumeración de tres estados como la que usted describe funcionará bien.
Hay todo tipo de otras formas de ser incierto. Tales preguntas incluyen:
Muchas de esas preguntas pueden tratarse usando probabilidades en el rango de 0.0 (falso) a 1.0 (verdadero), y aplicando matemática de coma flotante.
Un químico computacional y un informático llamado David E. Shaw aplicó este tipo de cosas a Wall Street y ahora tiene un valor de alrededor de $ 2.5 mil millones. Entonces sí, es útil. :-)
fuente
Hace muchos años jugué con algunos de los algoritmos que estaban surgiendo para asignar una creencia a los valores. Fue un poco divertido. En última instancia, lo que obtuve de él es que el booleano a menudo es un ajuste artificial. Realmente debería ser un trilean verdadero / falso / otro valor. En la experimentación que parecía conducir al "mejor" código para mí en ese momento. Desde entonces he cedido y hago lo que todos los demás hacen, mientras pienso internamente en lo simple que PODRÍA ser si dejáramos de hacer las cosas de la misma manera ... :-)
fuente
Sin embargo, las declaraciones de caso o cambio funcionarían bien para esto, utilizando números enteros para tratar arbitrariamente el cambio.
Además, en Ruby, mientras 'nil' regresa como falso en algunas circunstancias, si usa el operador de igualdad,
nil == false
regresafalse
, por lo que podría usar rubynil
para manejar la lógica ternaria.fuente
Otra opción en su caso podría ser invertir el control aplicando el principio "decir no preguntar" y cambiarlo a (perdón por la palabra adultez, bloqueo cerebral):
donde
OnlyAllowAdultsToLoginStrategy
implementa una interfaz:fuente
void userIsAdult()
hacer? Quizás quisiste decirbool userIsAdult()
?Mi hijo me preguntaba cómo implementar eficientemente pruebas que se parezcan a esto. Las banderas que se estaban probando solo eran verdaderas / falsas, pero las teclas de combinación tenían tres estados (debe ser cierto, debe ser falso o no me importa). Por supuesto, esto se puede implementar con una estructura de datos de 2 bits y un poco de giro, pero ese tipo de código realmente necesita ser comentado ya que el propósito no es fácil de discernir con solo mirar el código.
fuente
C tiene esta característica implementada en la mayoría de las funciones de la biblioteca. por ejemplo, strcmp compara 2 cadenas y devuelve 0 si son iguales, 1 (es decir, cualquier número entero positivo) si el primero es 'mayor' que el segundo y -1 (es decir, cualquier número entero negativo) si el segundo es mayor que el primero .
El mismo enfoque se puede utilizar en otro lugar, + / 0 / - como su tri-estado. También le permite realizar una lógica booleana en los valores si sabe 0 si es falso y cualquier otro valor es verdadero.
fuente
Para C ++, Boost en realidad implementa un Tribool descrito como tal:
fuente
La casilla de verificación VB6 tiene esta capacidad. Los valores de la casilla de verificación pueden ser 0 = apagado, 1 = encendido, 2 = en gris
fuente