Würden Sie einen Trilean (True, False, ??) verwenden? [Closed]

22

Manchmal habe ich eine Funktion, die wahr oder falsch zurückgeben sollte. Aber manchmal wären drei mögliche Werte sinnvoller.

In einigen Sprachen werden diese Fälle mit ganzen Zahlen oder mit Ausnahmen behandelt.

Zum Beispiel möchten Sie das Alter eines Benutzers behandeln, wenn er über 18 Jahre alt ist. Und Sie haben eine Funktion wie diese.

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

Aber in einigen Fällen, abhängig davon, wie Ihre App erstellt wurde, kann es vorkommen, dass das Geburtstagsfeld unvollständig ist. Dann sollte diese Funktion etwas Unbestimmtes zurückgeben.

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

Wie gesagt, wir können das mit Exceptions und Int umgehen, aber ich finde es ziemlich sexy, ein wahres, falsches, unbestimmtes eingebettetes Element in der Sprache zu haben, anstatt einige selbst definierte Konstanten zu verwenden.

Loïc Faure-Lacroix
quelle
15
Obligatorischer TDWTF-Link: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@ Anna Lear: Verdammt, du hast mich geschlagen. ^^
gablin
3
gablin: Verdammt, du hast mich sogar geschlagen, weil ich mich über Anna beschwert habe.
user281377
1
Ugh, ich wollte das T, F, FNF auch bekommen! schüttelt die Faust
Mike M.
4
@gablin, @ammoQ, @Mike M .: Entschuldigung. :)
Adam Lear

Antworten:

33

Dies kann mit Aufzählungen, Ganzzahlen, Symbolen (z. B. Lisp, Ruby), nullfähigen Typen (verwenden Sie null als unbestimmten Zustand), Optionstypen (z. B. ML) oder einem ähnlichen Konstrukt behandelt werden - abhängig von Ihrer Sprache.

Obwohl Ihr Beispiel und Ihre Begründung stichhaltig sind, sehe ich nicht, dass es auf der Prioritätenliste der zu entwickelnden Sprachfunktionen steht.

ChrisF
quelle
Null in C / C ++ soll gleich falsch sein. In diesen Fällen müssten Sie -1 zurückgeben. Ich denke, unbestimmter Zustand ist ziemlich häufig, wird aber immer anders behandelt, weil diese Syntax nicht wirklich existiert. In Java kann eine Boolesche Funktion für eine Boolesche Funktion nichts anderes als true oder false zurückgeben. Sie müssen also einen anderen Typ verwenden und den zurückgegebenen Wert gut dokumentieren.
Loïc Faure-Lacroix
@Sybiam - es ist nichts falsch mit der Verwendung einer anderen Art gegebenenfalls . Wie gesagt, ich kann ein Argument für einen Trinary-Typ sehen, aber ich kann nicht sehen, dass es in Kürze zu vorhandenen Sprachen hinzugefügt wird.
ChrisF
6
@Sybiam: In Java können Sie einen Booleschen Wert zurückgeben, der sein kann null. In C / C ++ können Sie eine Enumeration zurückgeben.
Macneil
das ist Wahnsinn!
Loïc Faure-Lacroix
2
@ Macneil vielleicht Sparta?
Syockit
5

Ich habe keinen Fall gesehen, in dem dies notwendig ist. Wenn dieses Feld in dem von Ihnen angegebenen Beispiel erforderlich ist, sollte es an einer anderen Stelle validiert worden sein. isAdult()ist von Natur aus eine Methode mit zwei Zuständen: Sie sind entweder oder Sie sind nicht. Es ist nicht erforderlich, dass es etwas anderes tut, als false zurückzugeben, wenn es auf Daten stößt, die es nicht verarbeiten kann. Zum Beispiel:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K
quelle
2
Wenn die Daten ungültig sind, kann der Benutzer aufgefordert werden, sie zu korrigieren. Dies unterscheidet sich von Minderjährigen, wenn Sie die Person nicht auffordern, ein neues Alter einzugeben. Dies ist 2 verschiedene Verhaltensweisen. Bei einigen sozialen Websites können Sie beispielsweise aus Datenschutzgründen unvollständige Geburtstage eingeben.
Loïc Faure-Lacroix
2
Ich denke, dass die Validierung in einem anderen Bereich / Codeabschnitt durchgeführt werden sollte. Überprüfen Sie zuerst die Daten und bearbeiten Sie sie dann.
Michael K
1
@Sybiam: Im Allgemeinen werden Daten von Anwendungen nicht willkürlich abgefragt, wenn sie benötigt werden. Sie könnten .isAdult()den Benutzer selbst abfragen, wenn Sie das wirklich wollen, und das würde besser funktionieren.
David Thornley
5

wahr, falsch, unbekannt

ja Nein Vielleicht

In C # können Sie einen NULL-fähigen Bool verwenden (Sie können sich jetzt entsetzt zurückziehen).

In MS-SQL können Sie ein nullbares Bitfeld verwenden (dito)

Steven A. Lowe
quelle
2
Das Problem mit nullbaren Booleschen Werten ist nicht, dass sie Nullen haben, so sehr, dass die meisten Leute (ich eingeschlossen) nichts über dreiwertige Logik wissen. Welches, für den Anfang: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar
Richtig / Falsch / Keine.
Lennart Regebro
2
Das Komische ist, dass viele Leute Binär-, Oktal- und Hexadezimalwerte verstehen, sich aber nicht auf Dreisterne konzentrieren können. Warum das? Gleiches, nur Basis drei ... das würde das Drei-Werte-Logik-Problem lösen.
Michael K
5
Die meisten Menschen haben nur Angst vor dem unknown.
Dan04
2

In C ++ kann dies mit einem Non- boolReturn-Typ oder durch Auslösen einer Ausnahme behandelt werden. Wenn Sie einen Rückgabetyp mit drei Werten wünschen, verwenden Sie ein enum. Es ist nicht so sexy, aber es funktioniert, und was noch wichtiger ist, Sie können es tun, ohne die Sprache für den Rest von uns durcheinander zu bringen.

Mit boolsei dreiwertigen Probleme verursachen würde. Wie gehen Sie vor bool foo; ... if (foo)..., wenn Sie fooeinen der drei Werte annehmen ? boolVariablen zu haben, die genau einer von ihnen sind foound !foozu jeder Zeit wahr sind , hat Vorteile . Es hilft, über Programme nachzudenken.

Überprüfen Sie, was Benutzer in der numerischen Verarbeitung tun, wenn sie möglicherweise NaNWerte erhalten. Es ist kompliziert. Ich möchte es lieber nicht für die normale boolesche Verarbeitung durchmachen müssen.

Wenn Sie nicht .isAdult()genügend Informationen verarbeiten möchten , müssen Sie dies intern tun und dann entweder trueoder zurückgeben false. Andernfalls müssen Sie jedes Mal, wenn Sie es verwenden, den Rückkehrcode überprüfen, bevor Sie etwas anderes tun, und eine Möglichkeit finden, damit umzugehen. Es würde bedeuten, dass Sie die Dokumente überprüfen müssten, um festzustellen, ob eine Funktion tatsächlich das getan hat, was der Name sagt, und das wäre eine Katastrophe für die Lesbarkeit.

David Thornley
quelle
2

Die Idee ist sehr nützlich. Es gibt ein ganzes Feld, das dem Umgang mit Unsicherheit gewidmet ist und Fuzzy Logic heißt .

Zum Glück für uns Programmierer können Sie Fuzzy-Logik mit Standard-Sprachfunktionen implementieren.

In dem von Ihnen angegebenen Fall können die unsicheren Informationen zum Beispiel leicht ermittelt werden, indem Sie den Benutzer fragen. Eine Tristate-Aufzählung, wie Sie sie beschreiben, funktioniert also einwandfrei.

Es gibt viele andere Möglichkeiten, unsicher zu sein. Solche Fragen umfassen:

  • Wird es morgen regnen? Es ist noch nicht geschehen, daher kann es niemand wissen - aber Sie können eine Vermutung anstellen und eine Wahrscheinlichkeit angeben.
  • Gibt es im Sonnensystem des Sterns Beta Pictoris mehrzelliges Leben auf einem Planeten? Es gibt eine eindeutige Ja-oder-Nein-Antwort, aber wir können derzeit nicht sagen, was das ist.

Viele dieser Fragen können mit Wahrscheinlichkeiten im Bereich von 0,0 (falsch) bis 1,0 (wahr) und Gleitkomma-Mathematik beantwortet werden.

Ein Computerchemiker und Informatiker namens David E. Shaw wandte so etwas an die Wall Street an und hat jetzt einen Wert von etwa 2,5 Milliarden US-Dollar. Also ja, es ist nützlich. :-)

Bob Murphy
quelle
1

Vor vielen Jahren habe ich mit einigen der Algorithmen gespielt, die herauskamen, um den Werten einen Glauben zuzuweisen. Hat Spaß gemacht. Letztendlich habe ich daraus gelernt, dass Boolesche Werte oft eine erfundene Passung sind. Eigentlich sollte es ein trileaner wahr / falsch / anderer Wert sein. Beim Experimentieren schien das zu der Zeit zu dem "besten" Code für mich zu führen. Ich bin seitdem zusammengebrochen und tue, was alle anderen tun, während ich intern überlegte, wie viel einfacher es sein KÖNNTE, wenn wir aufhören würden, Dinge auf die gleiche Weise wie früher zu tun ... :-)

Brian Knoblauch
quelle
0

Case- oder Switch-Anweisungen funktionieren jedoch einwandfrei, wenn Ganzzahlen verwendet werden, um willkürlich mit dem Switch umzugehen.

Wenn Sie in Ruby den Gleichheitsoperator verwenden, wird nil == falsein einigen Fällen 'nil' als false zurückgegeben false, sodass Sie Ruby nilfür die Behandlung der ternären Logik verwenden können.

philosodad
quelle
0

Eine andere Möglichkeit in Ihrem Fall könnte darin bestehen, das Steuerelement durch Anwenden des "Tell Don't Ask" -Prinzips umzukehren und in zu ändern (entschuldigen Sie das Wort "Adultness", "Brain Blockade"):

user.isAdult(new OnlyAllowAdultsToLogin())

wo OnlyAllowAdultsToLoginStrategyimplementiert eine Schnittstelle:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
flamingpenguin
quelle
Was macht void userIsAdult()das? Vielleicht meintest du bool userIsAdult()?
Timwi
0

Mein Sohn fragte mich, wie ich vergleichbare Tests effizient durchführen könne. Die getesteten Flags waren nur wahr / falsch, aber die Matchkeys hatten drei Zustände (Es muss wahr sein, es muss falsch sein, oder es ist mir egal). Natürlich kann dies mit einer 2-Bit-Datenstruktur und ein wenig Twiddling implementiert werden, aber diese Art von Code muss wirklich kommentiert werden, da der Zweck nicht einfach zu erkennen ist, wenn man sich nur den Code ansieht.

Omega Centauri
quelle
0

C hat diese Funktion in den meisten Bibliotheksfunktionen implementiert. Beispiel: strcmp vergleicht 2 Zeichenfolgen und gibt 0 zurück, wenn sie gleich sind, 1 (dh eine positive ganze Zahl), wenn die erste größer als die zweite ist, und -1 (dh eine negative ganze Zahl), wenn die zweite größer als die erste ist .

Der gleiche Ansatz kann an anderer Stelle verwendet werden, + / 0 / - als Ihr Tri-State. Sie können damit auch boolesche Logik für die Werte ausführen, wenn Sie 0 kennen, wenn false und jeder andere Wert true ist.

gbjbaanb
quelle
0

Für C ++ implementiert Boost tatsächlich ein Tribool, das als solches beschrieben wird:

Die Tribool-Klasse verhält sich wie der eingebaute Bool-Typ, jedoch für die boolesche Logik mit drei Zuständen. Die drei Zustände sind wahr, falsch und unbestimmt, wobei die ersten beiden Zustände denen des C ++ - Bool-Typs entsprechen und der letzte Zustand einen unbekannten booleschen Wert darstellt (der wahr oder falsch sein kann, wir wissen es nicht).

Matthieu
quelle
-1

Das Kontrollkästchen VB6 bietet diese Funktion. Die Kontrollkästchenwerte können 0 = aus, 1 = ein, 2 = grau sein

Dave
quelle