Você veria algum uso de um trileano (verdadeiro, falso, ??) [fechado]

22

Às vezes, tenho uma função que deve retornar verdadeira ou falsa. Mas, às vezes, três valores possíveis fariam mais sentido.

Em alguns idiomas, esses casos seriam tratados com números inteiros ou com exceções.

Por exemplo, você deseja lidar com a idade de um usuário se ele tiver mais de 18 anos de idade. E você tem uma função como esta.

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

Mas, em alguns casos, dependendo da forma como seu aplicativo é criado, pude ver casos em que o campo de aniversário está incompleto. Então essa função deve retornar algo indeterminado.

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

Como eu disse, podemos lidar com isso com Exceptions e Int, mas acho muito sexy ter uma verdadeira, falsa e indeterminada incorporada no idioma, em vez de usar algumas constantes definidas em casa.

Loïc Faure-Lacroix
fonte
15
Link obrigatório do TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@ Anna Lear: Porra, você me venceu. ^^
gablin
3
gablin: Porra, você até me venceu por reclamar de Anna.
user281377
1
Ugh, eu também queria pegar o T, F, FNF! sacode o punho
Mike M.
4
@gablin, @ammoQ, @Mike M .: Desculpe. :)
Adam Lear

Respostas:

33

Isso pode ser tratado com enumerações, números inteiros, símbolos (por exemplo, Lisp, Ruby), tipos anuláveis ​​(use null como estado indeterminado), tipos de opções (por exemplo, ML) ou alguma construção semelhante - dependendo do seu idioma.

Portanto, enquanto seu exemplo e lógica são sólidos, não consigo vê-lo na lista prioritária de recursos de linguagem a serem desenvolvidos.

ChrisF
fonte
nulo em C / C ++ deve ser falso. Nesses casos, você teria que retornar -1. Eu acho que o estado indeterminado é bastante frequente, mas sempre é tratado de maneira diferente, porque essa sintaxe realmente não existe. Em java, uma função booleana não pode retornar nada além de true ou false para uma função booleana. Então você é forçado a usar um tipo diferente e documentar bem o valor retornado.
Loïc Faure-Lacroix
@ Sybiam - não há nada errado em usar um tipo diferente, quando apropriado . Como eu disse, posso ver um argumento para um tipo trinário, mas não consigo vê-lo sendo adicionado aos idiomas existentes tão cedo.
ChrisF
6
@ Sybiam: Em Java, você pode retornar um booleano, que pode ser null. Em C / C ++, você pode retornar uma enumeração.
Macneil
isso é loucura!
Loïc Faure-Lacroix
2
@Macneil talvez Sparta?
syockit
5

Eu não vi um caso em que isso seja necessário. No exemplo que você deu, se esse campo for necessário, ele deverá ter sido validado em outro lugar. isAdult()é inerentemente um método de dois estados: você é ou não é. Não há necessidade de fazer nada além de retornar false se encontrar dados que não podem ser manipulados. Por exemplo:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K
fonte
2
Se os dados forem inválidos, ele poderá solicitar que o usuário o corrija, o que é diferente de ser menor de idade, onde você não solicita que a pessoa insira uma nova era. Este é 2 comportamentos diferentes. Por exemplo, alguns sites sociais permitem inserir aniversários incompletos para privacidade.
Loïc Faure-Lacroix
2
Penso que a validação deve ser realizada em outra área / seção de código. Valide os dados primeiro e depois opere.
Michael K
1
@ Sybiam: Em geral, os aplicativos não solicitam dados aleatoriamente, quando precisam. Você pode .isAdult()consultar o próprio usuário, se é isso o que realmente deseja, e isso funcionaria melhor.
David Thornley
5

verdadeiro, falso, desconhecido

sim não Talvez

em C #, você pode usar um bool anulável (você pode recuar horrorizado agora)

no MS-SQL, você pode usar um campo de bit anulável (idem)

Steven A. Lowe
fonte
2
O problema com os booleanos anuláveis ​​não é que eles tenham nulos, já que a maioria das pessoas (inclusive eu) não sabe nada sobre lógica de três valores. Qual deles, para começar: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar
Verdadeiro / Falso / Nenhum.
Lennart Regebro
2
O engraçado é que muitas pessoas entendem binário, octal e hexadecimal, mas não conseguem entender o que é ternário. Por que é que? mesma coisa, apenas base três ... isso resolveria o problema da lógica dos três valores.
Michael K
5
A maioria das pessoas só tem medo do unknown.
dan04
2

No C ++, isso pode ser tratado com um booltipo de não retorno ou lançando uma exceção. Se você deseja um tipo de retorno com três valores, use um enum. Não é tão sexy, mas funciona, e o mais importante é que você pode fazer isso sem bagunçar o idioma para o resto de nós.

Ter booltrês valores causaria problemas. Como você lida bool foo; ... if (foo)..., assumindo que foopossa ter algum dos três valores? Há vantagens em ter boolvariáveis ​​como essa fooe !foouma sempre verdadeira. Ajuda a raciocinar sobre programas.

Confira o que as pessoas fazem no processamento numérico quando podem obter NaNvalores. É complicado. Prefiro não ter que continuar com isso no processamento booleano comum.

Se você deseja .isAdult()manipular informações insuficientes, faça isso internamente e, em seguida, retorne um trueou false. Caso contrário, toda vez que você o usar, será necessário verificar o código de retorno antes de fazer qualquer outra coisa e criar uma maneira de lidar com isso. Isso significaria que você tinha que verificar os documentos para ver se uma função realmente fazia o que o nome dizia, e isso seria um desastre para facilitar a leitura.

David Thornley
fonte
2

A ideia é bastante útil. Há todo um campo dedicado a lidar com a incerteza chamada Fuzzy Logic .

Felizmente para nós, programadores, você pode implementar lógica nebulosa com recursos de linguagem padrão.

Por exemplo, no caso que você forneceu, as informações incertas são facilmente determináveis ​​perguntando ao usuário. Portanto, um enum de três estados como você descreve funcionará bem.

Existem todos os tipos de outras maneiras de ser incerto. Tais perguntas incluem:

  • Vai chover amanhã? Ainda não aconteceu, então ninguém pode saber - mas você pode adivinhar e dar uma probabilidade.
  • Existe vida multicelular em um planeta no sistema solar da estrela Beta Pictoris? Tem uma resposta definitiva de sim ou não, mas atualmente não podemos dizer o que é isso.

Muitas dessas questões podem ser tratadas usando probabilidades no intervalo de 0,0 (falso) a 1,0 (verdadeiro) e aplicando a matemática de ponto flutuante.

Um químico computacional e cientista da computação chamado David E. Shaw aplicou esse tipo de coisa a Wall Street e agora vale cerca de US $ 2,5 bilhões. Então, sim, é útil. :-)

Bob Murphy
fonte
1

Muitos anos atrás, eu brinquei com alguns dos algoritmos que surgiam para atribuir uma crença a valores. Foi divertido. Em última análise, o que eu ganhei com isso é que o booleano geralmente é um ajuste artificial. Realmente deve ser um valor verdadeiro / falso / outro trileano. Na experimentação, isso pareceu levar ao "melhor" código para mim na época. Desde então, eu desmoronei e fiz o que todo mundo faz, enquanto pensava internamente em como seria mais simples se parássemos de fazer as coisas da mesma maneira antiga ... :-)

Brian Knoblauch
fonte
0

As instruções Case ou Switch funcionariam bem para isso, porém, usando números inteiros para lidar arbitrariamente com a opção.

Além disso, em Ruby, enquanto 'nil' retorna como falso em algumas circunstâncias, se você usar o operador de igualdade, nil == falseretorna false, para que você possa usar ruby nilpara manipular a lógica ternária.

philosodad
fonte
0

Outra opção no seu caso pode ser inverter o controle aplicando o principal "diga não pergunte" e altere-o para (desculpe pela palavra adulto, bloqueio cerebral):

user.isAdult(new OnlyAllowAdultsToLogin())

onde OnlyAllowAdultsToLoginStrategyimplementa uma interface:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
flamingpenguin
fonte
O que void userIsAdult()faz? Talvez você quis dizer bool userIsAdult()?
Timwi
0

Meu filho estava me perguntando como implementar com eficiência testes que se assemelham a isso. Os sinalizadores sendo testados eram apenas verdadeiros / falsos, mas as teclas de combinação tinham três estados (deve ser verdadeiro, deve ser falso ou não me importo). É claro que isso pode ser implementado com uma estrutura de dados de 2 bits e um pouco de ajustes, mas esse tipo de código realmente precisa ser comentado, pois o objetivo não é fácil de discernir apenas olhando o código.

Omega Centauri
fonte
0

C possui esse recurso implementado na maioria das funções da biblioteca. por exemplo, strcmp compara 2 strings e retorna 0 se forem iguais, 1 (ou seja, qualquer número inteiro positivo) se o primeiro for 'maior' que o 2º e -1 (ou seja, qualquer número inteiro negativo) se o segundo for maior que o primeiro .

A mesma abordagem pode ser usada em outro lugar, + / 0 / - como seu estado tri. Também permite executar lógica booleana nos valores se você souber 0 se false e qualquer outro valor for true.

gbjbaanb
fonte
0

Para C ++, o Boost realmente implementa um Tribool descrito como tal:

A classe tribool age como o tipo bool interno, mas para a lógica booleana de 3 estados. Os três estados são verdadeiros, falsos e indeterminados, onde os dois primeiros estados são equivalentes aos do tipo booleano C ++ e o último estado representa um valor booleano desconhecido (que pode ser verdadeiro ou falso, não sabemos).

Matthieu
fonte
-1

A caixa de seleção VB6 possui esse recurso. Os valores da caixa de seleção podem ser 0 = desativado, 1 = ativado, 2 = acinzentado

Dave
fonte