Envisageriez-vous une utilisation d'un Trilean (Vrai, Faux, ??) [fermé]

22

Parfois, j'ai une fonction qui devrait retourner vrai ou faux. Mais parfois, trois valeurs possibles auraient plus de sens.

Dans certains langages, ces cas seraient traités avec des nombres entiers ou avec des exceptions.

Par exemple, vous voulez gérer l'âge d'un utilisateur s'il a plus de 18 ans. Et vous avez une fonction comme celle-ci.

if(user.isAdult(country_code)){
     //Go On
}else{
     // Block access or do nothing
}

Mais dans certains cas, selon la façon dont votre application est créée, je pouvais voir le cas où le champ d'anniversaire était incomplet. Ensuite, cette fonction devrait renvoyer quelque chose d'indéterminé.

switch(user.isAdult()){
    case true:
        // go on
        break;
    case undetermined:
        //Inform user birthday is incomplete
    case false:
        //Block access
}

Comme je l'ai dit, nous pouvons gérer cela avec Exceptions et Int, mais je trouverais assez sexy d'avoir un vrai, faux, indéterminé intégré dans la langue au lieu d'utiliser des constantes définies à la maison.

Loïc Faure-Lacroix
la source
15
Lien TDWTF obligatoire: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@Anna Lear: Merde, tu m'as battu. ^^
gablin
3
gablin: Merde, tu m'as même battu pour me plaindre d'Anna.
user281377
1
Ugh, je voulais aussi obtenir le T, F, FNF! secoue le poing
Mike M.
4
@gablin, @ammoQ, @Mike M .: Désolé. :)
Adam Lear

Réponses:

33

Cela peut être géré avec des énumérations, des entiers, des symboles (par exemple, Lisp, Ruby), des types nullables (utilisez null comme état indéterminé), des types d'options (par exemple, ML) ou une construction similaire - en fonction de votre langue.

Donc, bien que votre exemple et votre justification soient solides, je ne peux pas le voir figurer sur la liste prioritaire des fonctionnalités linguistiques à développer.

ChrisF
la source
null en C / C ++ est supposé égal à false. Dans ces cas, vous devez retourner -1. Je pense que l'état indéterminé est assez fréquent mais est toujours traité différemment car cette syntaxe n'existe pas vraiment. En java, une fonction booléenne ne peut renvoyer autre chose que vrai ou faux pour une fonction booléenne. Vous êtes donc obligé d'utiliser un type différent et de bien documenter la valeur retournée.
Loïc Faure-Lacroix
@Sybiam - il n'y a rien de mal à utiliser un type différent le cas échéant . Comme je l'ai dit, je peux voir un argument pour un type trinaire, mais je ne vois pas qu'il soit ajouté aux langues existantes de si tôt.
ChrisF
6
@Sybiam: En Java, vous pouvez renvoyer un booléen, qui peut être null. En C / C ++, vous pouvez renvoyer une énumération.
Macneil
c'est de la folie!
Loïc Faure-Lacroix
2
@Macneil peut-être Sparta?
syockit
5

Je n'ai vu aucun cas où cela soit nécessaire. Dans l'exemple que vous avez donné, si ce champ est nécessaire, il aurait dû être validé ailleurs. isAdult()est intrinsèquement une méthode à deux états: vous l'êtes ou vous ne l'êtes pas. Il n'est pas nécessaire de le faire faire autre chose que de retourner false s'il rencontre des données qu'il ne peut pas gérer. Par exemple:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K
la source
2
Si les données ne sont pas valides, il peut demander à l'utilisateur de les corriger, ce qui est différent de l'âge mineur où vous ne demandez pas à la personne d'entrer un nouvel âge. Il s'agit de 2 comportements différents. Par exemple, certains sites sociaux vous permettent de saisir des anniversaires incomplets pour la confidentialité.
Loïc Faure-Lacroix
2
Je pense que la validation devrait être effectuée dans une autre zone / section de code. Validez d'abord les données, puis opérez-les.
Michael K
1
@Sybiam: En général, les applications ne demandent pas de données au hasard, quand elles en ont besoin. Vous auriez pu .isAdult()interroger l'utilisateur lui-même, si c'est vraiment ce que vous voulez, et cela fonctionnerait mieux.
David Thornley
5

vrai, faux, inconnu

Oui Non peut-être

en C #, vous pouvez utiliser un bool nullable (vous pouvez reculer d'horreur maintenant)

dans MS-SQL, vous pouvez utiliser un champ de bit nullable (idem)

Steven A. Lowe
la source
2
Le problème avec les booléens nullables n'est pas qu'ils ont des null, autant que la plupart des gens (moi y compris) ne savent rien de la logique à trois valeurs. Lequel, pour commencer: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar
Vrai / faux / aucun.
Lennart Regebro
2
Ce qui est drôle, c'est que beaucoup de gens comprennent le binaire, l'octal et l'hex, mais ne peuvent pas se concentrer sur le ternaire. Pourquoi donc? même chose, juste base trois ... qui résoudrait le problème de la logique à trois valeurs.
Michael K
5
La plupart des gens ont juste peur du unknown.
dan04
2

En C ++, cela peut être géré avec un booltype non- retour, ou en lançant une exception. Si vous voulez un type de retour à trois valeurs, utilisez un enum. Ce n'est pas aussi sexy, mais cela fonctionne, et ce qui est plus important, vous pouvez le faire sans gâcher la langue pour le reste d'entre nous.

Le fait d' boolavoir trois valeurs causerait des problèmes. Comment gérez-vous bool foo; ... if (foo)..., en supposant qu'il foopourrait avoir l'une des trois valeurs? Il y a des avantages à avoir des boolvariables telles que précisément l'une de fooet !fooest vraie à tout moment. Cela aide à raisonner sur les programmes.

Découvrez ce que les gens font dans le traitement numérique lorsqu'ils peuvent éventuellement obtenir des NaNvaleurs. C'est compliqué. Je préfère ne pas avoir à passer par là pour le traitement booléen ordinaire.

Si vous souhaitez .isAdult()gérer des informations insuffisantes, faites-le faire en interne, puis retournez soit trueou false. Sinon, chaque fois que vous l'utilisez, vous devez vérifier le code retour avant de faire quoi que ce soit d'autre et trouver un moyen de le gérer. Cela signifierait que vous deviez vérifier les documents pour voir si une fonction faisait réellement ce que son nom disait, et ce serait un désastre pour la lisibilité.

David Thornley
la source
2

L'idée est assez utile. Il y a tout un domaine consacré à la gestion de l'incertitude appelé Fuzzy Logic .

Heureusement pour nous, programmeurs, vous pouvez implémenter une logique floue avec des fonctionnalités de langage standard.

Par exemple, dans le cas que vous avez donné, les informations incertaines sont facilement déterminables en demandant à l'utilisateur. Une énumération à trois états comme celle que vous décrivez fonctionnera donc bien.

Il y a toutes sortes d'autres façons d'être incertain. Ces questions comprennent:

  • Pleuvra-t-il demain? Cela ne s'est pas encore produit, donc personne ne peut le savoir - mais vous pouvez faire une supposition éclairée et donner une probabilité.
  • Existe-t-il une vie multicellulaire sur une planète du système solaire de l'étoile Beta Pictoris? Il a une réponse définitive par oui ou par non, mais nous ne pouvons pas actuellement dire ce que c'est.

Beaucoup de ces questions peuvent être traitées en utilisant des probabilités comprises entre 0,0 (faux) et 1,0 (vrai), et en appliquant des mathématiques à virgule flottante.

Un chimiste en informatique et informaticien du nom de David E. Shaw a appliqué ce genre de chose à Wall Street et vaut maintenant environ 2,5 milliards de dollars. Alors oui, c'est utile. :-)

Bob Murphy
la source
1

Il y a plusieurs années, j'ai joué avec certains des algorithmes qui sortaient pour attribuer une croyance aux valeurs. C'était assez amusant. En fin de compte, ce que j'ai gagné, c'est que le booléen est souvent un ajustement artificiel. Vraiment, ce devrait être une valeur triléenne vrai / faux / autre. Dans l'expérimentation qui a semblé conduire au "meilleur" code pour moi à l'époque. J'ai depuis cédé et fait ce que tout le monde fait, tout en pensant en interne à quel point cela POURRAIT être plus simple si nous arrêtions de faire les choses de la même manière ... :-)

Brian Knoblauch
la source
0

Les instructions Case ou Switch fonctionneraient bien pour cela, cependant, en utilisant des entiers pour traiter arbitrairement le commutateur.

De plus, dans Ruby, alors que «nil» renvoie false dans certaines circonstances, si vous utilisez l'opérateur d'égalité, nil == falserenvoie false, vous pouvez donc utiliser ruby nilpour gérer la logique ternaire.

philosodad
la source
0

Une autre option dans votre cas pourrait être d'inverser le contrôle en appliquant le principe "ne demandez pas" et de le changer en (désolé pour le mot adulte, blocage cérébral):

user.isAdult(new OnlyAllowAdultsToLogin())

OnlyAllowAdultsToLoginStrategyimplémente une interface:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
pingouin flamant
la source
Que fait void userIsAdult()-il? Peut-être que vous vouliez dire bool userIsAdult()?
Timwi
0

Mon fils me demandait comment implémenter efficacement des tests qui ressemblent à ça. Les drapeaux testés n'étaient que vrai / faux, mais les clés de match avaient trois états (ça doit être vrai, ça doit être faux, ou je m'en fiche). Bien sûr, cela peut être implémenté avec une structure de données 2 bits et un peu de torsion, mais ce type de code doit vraiment être commenté car le but n'est pas facile à discerner de simplement regarder le code.

Omega Centauri
la source
0

C a cette fonctionnalité implémentée dans la plupart des fonctions de bibliothèque. par exemple strcmp compare 2 chaînes et retourne 0 si elles sont identiques, 1 (c'est-à-dire tout entier positif) si le 1er est 'supérieur' au 2e, et -1 (c'est à dire tout entier négatif) si le second est supérieur au premier .

La même approche peut être utilisée ailleurs, + / 0 / - comme votre tri-état. Il vous permet également d'effectuer une logique booléenne sur les valeurs si vous connaissez 0 si faux et que toute autre valeur est vraie.

gbjbaanb
la source
0

Pour C ++, Boost implémente en fait un Tribool décrit comme tel:

La classe tribool agit comme le type booléen intégré, mais pour une logique booléenne à 3 états. Les trois états sont vrai, faux et indéterminé, où les deux premiers états sont équivalents à ceux du type booléen C ++ et le dernier état représente une valeur booléenne inconnue (qui peut être vrai ou faux, nous ne savons pas).

Matthieu
la source
-1

La case à cocher VB6 a cette capacité. Les valeurs des cases à cocher peuvent être 0 = désactivé, 1 = activé, 2 = grisé

Dave
la source