Czy widzisz jakieś zastosowanie Trileana (prawda, fałsz?) [Zamknięte]

22

Czasami mam funkcję, która powinna zwracać wartość prawda lub fałsz. Ale czasami trzy możliwe wartości miałyby większy sens.

W niektórych tezach językowych przypadki byłyby obsługiwane za pomocą liczb całkowitych lub wyjątków.

Na przykład chcesz poradzić sobie z wiekiem użytkownika, który ma ponad 18 lat. I masz taką funkcję.

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

Ale w niektórych przypadkach, w zależności od budowy aplikacji, mogłem zobaczyć przypadek, w którym pole urodzin jest niepełne. Wtedy ta funkcja powinna zwrócić coś nieokreślonego.

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

Jak powiedziałem, możemy sobie z tym poradzić z Exceptions i Int, ale uważam, że to całkiem seksowne, aby mieć prawdziwe, fałszywe, nieokreślone osadzone w języku zamiast używać stałych zdefiniowanych w domu.

Loïc Faure-Lacroix
źródło
15
Obowiązkowy link TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@Anna Lear: Cholera, pobiłaś mnie do tego. ^^
gablin
3
gablin: Cholera, nawet pobiłeś mnie, że narzekałem na Annę.
user281377,
1
Ugh, też chciałem zdobyć T, F, FNF! potrząsa pięścią
Mike M.
4
@gablin, @ammoQ, @Mike M .: Przepraszamy. :)
Adam Lear

Odpowiedzi:

33

Można to obsłużyć za pomocą wyliczeń, liczb całkowitych, symboli (np. Lisp, Ruby), typów zerowalnych (użyj null jako nieokreślonego stanu), typów opcji (np. ML) lub podobnej konstrukcji - w zależności od języka.

Więc chociaż twój przykład i uzasadnienie są solidne, nie widzę, aby znajdowało się na liście priorytetowej funkcji językowych do opracowania.

ChrisF
źródło
null w C / C ++ ma być równy false. W takich przypadkach musisz zwrócić -1. Myślę, że nieokreślony stan jest dość częsty, ale zawsze jest traktowany inaczej, ponieważ ta składnia tak naprawdę nie istnieje. W języku Java funkcja boolowska nie może zwrócić niczego innego niż prawda lub fałsz dla funkcji boolowskiej. Jesteś więc zmuszony użyć innego typu i dobrze udokumentować zwróconą wartość.
Loïc Faure-Lacroix
@Sybiam - nie ma nic złego w używaniu innego typu, tam gdzie jest to właściwe . Jak powiedziałem, widzę argument za typem trójstronnym, ale nie widzę, aby został on wkrótce dodany do istniejących języków.
ChrisF
6
@Sybiam: W Javie możesz zwrócić wartość logiczną, którą może być null. W C / C ++ możesz zwrócić enum.
Macneil,
to szaleństwo!
Loïc Faure-Lacroix,
2
@Macneil może Sparta?
syockit,
5

Nie widziałem przypadku, w którym byłoby to konieczne. W podanym przykładzie, jeśli to pole jest konieczne, powinno zostać sprawdzone w innym miejscu. isAdult()jest nieuchronnie metodą dwustanową: albo jesteś albo nie jesteś. Nie trzeba nic robić, ale zwraca wartość false, jeśli napotka dane, których nie może obsłużyć. Na przykład:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K.
źródło
2
Jeśli dane są nieprawidłowe, może poprosić użytkownika o ich poprawienie, co jest inne niż nieletni, gdy nie poprosisz osoby o wprowadzenie nowego wieku. To są 2 różne zachowania. Na przykład niektóre witryny społecznościowe pozwalają wprowadzić niepełne urodziny dla zachowania prywatności.
Loïc Faure-Lacroix,
2
Myślę, że sprawdzanie poprawności powinno odbywać się w innym obszarze / sekcji kodu. Najpierw sprawdź poprawność danych, a następnie działaj na nich.
Michael K
1
@Sybiam: Zasadniczo aplikacje nie proszą o dane przypadkowo, kiedy ich potrzebują. Możesz .isAdult()zapytać samego użytkownika, jeśli naprawdę tego chcesz, a to działałoby lepiej.
David Thornley,
5

prawda, fałsz, nieznane

tak nie może

w C # możesz użyć zerowalnego boola (możesz teraz odskoczyć z przerażeniem)

w MS-SQL możesz użyć zerowego pola bitowego (to samo)

Steven A. Lowe
źródło
2
Problem z zerowalnymi wartościami logicznymi nie polega na tym, że mają one wartości zerowe, ponieważ większość ludzi (w tym ja) nie wie nic o logice trójwartościowej. Który, na początek: scientopia.org/blogs/goodmath/2010/08/24/…
Frank
Prawda / Fałsz / Brak.
Lennart Regebro
2
Zabawne jest to, że wiele osób rozumie układ binarny, ósemkowy i heksadecymalny, ale nie może otoczyć swoich umysłów trójka. Dlaczego? to samo, tylko podstawa trzy ... to rozwiązałoby problem logiki trzech wartości.
Michael K
5
Większość ludzi po prostu boi się unknown.
dan04
2

W C ++ można to obsłużyć za pomocą typu non- boolreturn lub przez zgłoszenie wyjątku. Jeśli chcesz trójwartościowy typ zwrotu, użyj enum. Nie jest tak seksowny, ale działa, a co ważniejsze, możesz to zrobić bez zepsucia języka dla reszty z nas.

Posiadanie booltrzech wartości spowodowałoby problemy. Jak sobie z tym poradzić bool foo; ... if (foo)..., zakładając, że foomoże mieć jedną z trzech wartości? Zalety posiadania boolzmiennych takich, które są dokładnie jedną z nich fooi !foosą prawdziwe przez cały czas. Pomaga rozumować o programach.

Sprawdź, co ludzie robią w przetwarzaniu numerycznym, kiedy mogą uzyskać NaNwartości. To skomplikowane. Wolałbym nie przechodzić przez to do zwykłego przetwarzania wartości logicznych.

Jeśli chcesz .isAdult()obsługiwać niewystarczające informacje, które mają to zrobić wewnętrznie, a następnie powrócić albo truealbo false. W przeciwnym razie za każdym razem, gdy go użyjesz, musisz sprawdzić kod powrotu przed zrobieniem czegokolwiek innego i znaleźć sposób na jego obsługę. Oznaczałoby to, że musisz sprawdzić dokumenty, aby zobaczyć, czy funkcja rzeczywiście zrobiła to, co jej nazwa mówi, że to zrobiła, a to byłoby katastrofą dla czytelności.

David Thornley
źródło
2

Pomysł jest dość przydatny. Jest całe pole poświęcone radzeniu sobie z niepewnością, zwane logiką rozmytą .

Na szczęście dla nas, programistów, można wdrożyć logikę rozmytą ze standardowymi funkcjami językowymi.

Na przykład w podanym przez ciebie przypadku niepewne informacje można łatwo ustalić, pytając użytkownika. Tak więc wyliczenie trójstanowe, jak opisujesz, będzie działać dobrze.

Istnieją różne sposoby, aby być niepewnym. Takie pytania obejmują:

  • Czy jutro będzie padać? To się jeszcze nie wydarzyło, więc nikt nie może wiedzieć - ale możesz zgadywać i dać prawdopodobieństwo.
  • Czy istnieje życie wielokomórkowe na planecie w układzie słonecznym gwiazdy Beta Pictoris? Ma jednoznaczną odpowiedź „tak lub nie”, ale nie możemy obecnie powiedzieć, co to jest.

Wiele z tych pytań można rozwiązać za pomocą prawdopodobieństw w zakresie od 0,0 (fałsz) do 1,0 (prawda) i stosując matematykę zmiennoprzecinkową.

Chemik obliczeniowy i informatyk David E. Shaw zastosował tego rodzaju rzeczy na Wall Street i jest teraz wart około 2,5 miliarda dolarów. Tak, to jest przydatne. :-)

Bob Murphy
źródło
1

Wiele lat temu bawiłem się niektórymi algorytmami wychodzącymi z przypisywania wiary wartościom. To była dobra zabawa. Ostatecznie zyskałem dzięki temu, że wartość logiczna jest często wymyślnym dopasowaniem. Naprawdę powinna to być trójlistna wartość prawda / fałsz / inna wartość. W eksperymentach wydawało mi się, że w owym czasie otrzymałem „najlepszy” kod. Od tamtej pory ułożyłem się i robiłem to, co robią wszyscy inni, jednocześnie myśląc wewnętrznie, o ile prostsze mogłoby być, gdybyśmy przestali robić rzeczy w ten sam stary sposób ... :-)

Brian Knoblauch
źródło
0

Instrukcje Case lub Switch działałyby w tym przypadku dobrze, wykorzystując liczby całkowite do arbitralnego radzenia sobie z przełącznikiem.

Również w Ruby, podczas gdy „zero” w niektórych okolicznościach zwraca wartość false, jeśli użyjesz operatora równości, nil == falsezwraca false, więc możesz użyć ruby nildo obsługi logiki trójskładnikowej.

filozofodad
źródło
0

Inną opcją w twoim przypadku może być odwrócenie kontroli poprzez zastosowanie zasady „mów nie pytaj” i zmień ją na (przepraszam za słowo „dorosłość”, „blokada mózgu”):

user.isAdult(new OnlyAllowAdultsToLogin())

gdzie OnlyAllowAdultsToLoginStrategyimplementuje interfejs:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
Flamingpenguin
źródło
Co ma void userIsAdult()zrobić? Może miałeś na myśli bool userIsAdult()?
Timwi
0

Mój syn pytał mnie, jak efektywnie wdrożyć podobne do tego testy. Testowane flagi były tylko prawdą / fałszem, ale klucze dopasowania miały trzy stany (musi to być prawda, musi być fałszem, inaczej mnie to nie obchodzi). Oczywiście można to zaimplementować za pomocą 2-bitowej struktury danych i odrobinę kręcącego się kodu, ale ten rodzaj kodu naprawdę musi zostać skomentowany, ponieważ cel nie jest łatwy do odróżnienia od samego spojrzenia na kod.

Omega Centauri
źródło
0

C ma tę funkcję zaimplementowaną w większości funkcji bibliotecznych. np. strcmp porównuje 2 łańcuchy i zwraca 0, jeśli są one takie same, 1 (tj. dowolna dodatnia liczba całkowita), jeśli pierwsza jest „większa” niż druga, i -1 (tj. dowolna liczba całkowita ujemna), jeśli druga jest większa niż pierwsza .

To samo podejście można zastosować gdzie indziej, + / 0 / - jako twój stan trójstronny. Pozwala także wykonywać logiczną wartość logiczną na wartościach, jeśli znasz 0, jeśli fałsz i dowolna inna wartość jest prawdą.

gbjbaanb
źródło
0

W przypadku C ++ Boost faktycznie implementuje Tribool opisany jako taki:

Klasa tribool działa jak wbudowany typ bool, ale dla 3-stanowej logiki boolowskiej. Trzy stany są prawdziwe, fałszywe i nieokreślone, przy czym pierwsze dwa stany są równoważne stanom typu bool C ++, a ostatni stan reprezentuje nieznaną wartość boolowską (może to być prawda lub fałsz, nie wiemy).

Matthieu
źródło
-1

Pole wyboru VB6 ma tę funkcję. Wartości pól wyboru mogą być 0 = wyłączone, 1 = włączone, 2 = wyszarzone

Dave
źródło