¿Verías algún uso de un Trilean (Verdadero, Falso, ??) [cerrado]

22

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.

Loïc Faure-Lacroix
fuente
15
Enlace obligatorio de TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@ Anna Lear: Maldición, me ganaste. ^^
gablin
3
gablin: Maldición, incluso me ganaste a quejarme de Anna.
usuario281377
1
¡Ugh, yo también quería obtener el T, F, FNF! sacude el puño
Mike M.
44
@gablin, @ammoQ, @Mike M .: Lo siento. :)
Adam Lear

Respuestas:

33

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.

ChrisF
fuente
nulo en C / C ++ se supone que es igual a falso. En estos casos, tendría que devolver -1. Creo que el estado indeterminado es bastante frecuente, pero siempre se trata de manera diferente porque esta sintaxis realmente no existe. En java, una función booleana no puede devolver nada más que verdadero o falso para una función booleana. Por lo tanto, se ve obligado a utilizar un tipo diferente y documentar bien el valor devuelto.
Loïc Faure-Lacroix
@Sybiam: no hay nada de malo en usar un tipo diferente cuando sea apropiado . Como dije, puedo ver un argumento para un tipo trinario, pero no puedo ver que se agregue a los idiomas existentes en el corto plazo.
ChrisF
66
@Sybiam: en Java puede devolver un booleano, que puede ser null. En C / C ++ puede devolver una enumeración.
Macneil
¡esto es una locura!
Loïc Faure-Lacroix
2
@Macneil tal vez Sparta?
syockit
5

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:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K
fuente
2
Si los datos no son válidos, puede pedirle al usuario que lo arregle, lo cual es diferente de ser menor de edad, donde no le pide a la persona que ingrese una nueva era. Esto es 2 comportamientos diferentes. Por ejemplo, algunos sitios sociales le permiten ingresar cumpleaños incompletos para mayor privacidad.
Loïc Faure-Lacroix
2
Creo que la validación debe realizarse en otra área / sección de código. Valide primero los datos y luego opere con ellos.
Michael K
1
@Sybiam: en general, las aplicaciones no solicitan datos de manera fortuita cuando la necesitan. Podría haber .isAdult()consultado al usuario mismo, si eso es realmente lo que desea, y eso funcionaría mejor.
David Thornley
5

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)

Steven A. Lowe
fuente
2
El problema con los booleanos anulables no es que tengan valores nulos, por lo que la mayoría de las personas (incluido yo) no saben nada acerca de la lógica de tres valores. Cuál, para empezar: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar
Verdadero / Falso / Ninguno.
Lennart Regebro
2
Lo curioso es que mucha gente entiende binario, octal y hexadecimal, pero no puede entender lo ternario. ¿Porqué es eso? Lo mismo, solo base tres ... eso resolvería el problema de la lógica de tres valores.
Michael K
55
La mayoría de las personas simplemente temen a la unknown.
dan04
2

En C ++, esto se puede manejar con un booltipo sin retorno o lanzando una excepción. Si desea un tipo de retorno de tres valores, use un enum. 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 booltres valores causaría problemas. ¿Cómo se maneja bool foo; ... if (foo)..., suponiendo que foopueda tener alguno de los tres valores? Hay ventajas en tener boollas variables de tal manera que, precisamente, uno de los fooy !fooes 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 NaNvalores. 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 devuelva trueo false. 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.

David Thornley
fuente
2

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:

  • ¿Lloverá mañana? Todavía no ha sucedido, por lo que nadie puede saberlo, pero puedes hacer una suposición educada y dar una probabilidad.
  • ¿Hay vida multicelular en un planeta en el sistema solar de la estrella Beta Pictoris? Tiene una respuesta definitiva de sí o no, pero actualmente no podemos decir qué es eso.

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. :-)

Bob Murphy
fuente
1

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 ... :-)

Brian Knoblauch
fuente
0

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 == falseregresa false, por lo que podría usar ruby nilpara manejar la lógica ternaria.

filosodad
fuente
0

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):

user.isAdult(new OnlyAllowAdultsToLogin())

donde OnlyAllowAdultsToLoginStrategyimplementa una interfaz:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
flamingpenguin
fuente
¿Qué void userIsAdult()hacer? Quizás quisiste decir bool userIsAdult()?
Timwi
0

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.

Omega Centauri
fuente
0

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.

gbjbaanb
fuente
0

Para C ++, Boost en realidad implementa un Tribool descrito como tal:

La clase tribool actúa como el tipo bool incorporado, pero para la lógica booleana de 3 estados. Los tres estados son verdaderos, falsos e indeterminados, donde los dos primeros estados son equivalentes a los del tipo bool de C ++ y el último estado representa un valor booleano desconocido (que puede ser verdadero o falso, no lo sabemos).

Matthieu
fuente
-1

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

Dave
fuente