Apakah Anda melihat ada penggunaan Trilean (Benar, Salah, ??) [ditutup]

22

Terkadang saya memiliki fungsi yang harus mengembalikan benar atau salah. Tetapi terkadang tiga nilai yang mungkin lebih masuk akal.

Dalam beberapa tesis bahasa kasus akan ditangani dengan bilangan bulat atau dengan pengecualian.

Misalnya, Anda ingin menangani usia pengguna jika ia berusia di atas 18 tahun. Dan Anda memiliki fungsi seperti ini.

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

Tetapi dalam beberapa kasus tergantung bagaimana aplikasi Anda dibangun saya bisa melihat kasus di mana bidang ulang tahun tidak lengkap. Maka fungsi ini harus mengembalikan sesuatu yang tidak ditentukan.

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

Seperti yang saya katakan kita bisa mengatasinya dengan Pengecualian dan Int, tapi saya akan merasa cukup seksi untuk memiliki embeded yang benar, salah, tidak ditentukan dalam bahasa daripada menggunakan beberapa konstanta yang didefinisikan di rumah.

Loïc Faure-Lacroix
sumber
15
Tautan wajib TDWTF: thedailywtf.com/Articles/What_Is_Truth_0x3f_.aspx :)
Adam Lear
2
@Anna Lear: Sial, Anda mengalahkan saya untuk itu. ^^
gablin
3
gablin: Sial, kau bahkan memukulku hingga mengeluh tentang Anna.
user281377
1
Ugh, aku juga ingin mendapatkan T, F, FNF! getar kepalan tangan
Mike M.
4
@ gablin, @ammoQ, @Mike M .: Maaf. :)
Adam Lear

Jawaban:

33

Ini dapat ditangani dengan enum, bilangan bulat, simbol (misalnya, Lisp, Ruby), jenis yang dapat dibatalkan (gunakan null sebagai keadaan tak tentu), jenis opsi (misalnya, ML), atau beberapa konstruksi serupa - tergantung pada bahasa Anda.

Jadi, sementara contoh dan alasan Anda masuk akal, saya tidak dapat melihatnya sebagai daftar prioritas fitur bahasa untuk dikembangkan.

ChrisF
sumber
null dalam C / C ++ seharusnya sama dengan false. Dalam kasus ini, Anda harus mengembalikan -1. Saya pikir keadaan yang tidak ditentukan cukup sering tetapi selalu diperlakukan secara berbeda karena sintaks ini tidak benar-benar ada. Dalam java, fungsi boolean tidak dapat mengembalikan apa pun selain benar atau salah untuk fungsi boolean. Jadi, Anda terpaksa menggunakan jenis yang berbeda dan mendokumentasikan dengan baik nilai yang dikembalikan.
Loïc Faure-Lacroix
@ Sibiam - tidak ada yang salah dengan menggunakan jenis yang berbeda jika sesuai . Seperti yang saya katakan saya bisa melihat argumen untuk tipe trinary, tapi saya tidak bisa melihatnya ditambahkan ke bahasa yang ada dalam waktu dekat.
ChrisF
6
@ Sibiam: Di Jawa Anda bisa mengembalikan Boolean, yang bisa jadi null. Dalam C / C ++ Anda dapat mengembalikan enum.
Macneil
ini adalah kegilaan!
Loïc Faure-Lacroix
2
@ Macneil mungkin Sparta?
syockit
5

Saya belum melihat kasus di mana ini perlu. Dalam contoh yang Anda berikan, jika bidang itu diperlukan, seharusnya sudah divalidasi di tempat lain. isAdult()secara inheren adalah metode dua-negara: Anda salah atau tidak. Tidak perlu membuatnya melakukan apa pun kecuali mengembalikan false jika menemukan data yang tidak dapat ditangani. Contohnya:

switch(user.isAdult()){
   case true:
      // go on
      break;
   default:
      // Block access.
}
Michael K.
sumber
2
Jika data tidak valid, ia dapat meminta pengguna untuk memperbaikinya yang berbeda dengan yang di bawah umur di mana Anda tidak meminta orang tersebut memasukkan usia baru. Ini adalah 2 perilaku berbeda. Sebagai contoh, beberapa situs sosial memungkinkan Anda memasukkan tanggal lahir yang tidak lengkap untuk privasi.
Loïc Faure-Lacroix
2
Saya pikir validasi harus dilakukan di area / bagian kode lainnya. Validasi data terlebih dahulu, lalu operasikan.
Michael K
1
@ Sibiam: Secara umum, aplikasi tidak meminta data secara serampangan, ketika mereka membutuhkannya. Anda dapat .isAdult()meminta pengguna itu sendiri, jika itu yang Anda inginkan, dan itu akan bekerja lebih baik.
David Thornley
5

benar, salah, tidak dikenal

ya Tidak mungkin

di C # Anda dapat menggunakan bool nullable (Anda dapat mundur dengan ketakutan sekarang)

dalam MS-SQL, Anda dapat menggunakan bidang bit yang dapat dibatalkan (ditto)

Steven A. Lowe
sumber
2
Masalah dengan boolean nullable bukan karena mereka memiliki null, sehingga kebanyakan orang (termasuk saya) tidak tahu apa-apa tentang logika bernilai tiga. Yang mana, sebagai permulaan: scientopia.org/blogs/goodmath/2010/08/24/…
Frank Shearar
Benar / Salah / Tidak ada.
Lennart Regebro
2
Lucunya, banyak orang yang mengerti biner, oktal, dan hex, tetapi tidak bisa membungkus pikiran mereka dengan ternary. Mengapa demikian? hal yang sama, hanya basis tiga ... yang akan memecahkan masalah logika nilai tiga.
Michael K
5
Sebagian besar orang hanya memiliki rasa takut terhadap unknown.
dan04
2

Dalam C ++, ini bisa ditangani dengan tipe tidak- boolkembali, atau dengan melemparkan pengecualian. Jika Anda ingin tipe pengembalian tiga nilai, gunakan aenum . Ini tidak seksi, tetapi berhasil, dan yang lebih penting Anda dapat melakukannya tanpa mengacaukan bahasa untuk kita semua.

Memiliki nilai booltiga akan menyebabkan masalah. Bagaimana Anda menangani bool foo; ... if (foo)..., dengan asumsi foomungkin memiliki salah satu dari ketiga nilai tersebut? Ada keuntungan memiliki boolvariabel sedemikian rupa sehingga justru salah satu dari foodan!foo benar setiap saat. Ini membantu alasan tentang program.

Lihat apa yang dilakukan orang dalam pemrosesan numerik ketika mereka mungkin mendapatkan NaNnilai. Ini rumit. Saya lebih suka tidak harus melaluinya untuk pemrosesan boolean biasa.

Jika Anda ingin .isAdult()menangani informasi yang tidak mencukupi, lakukan itu secara internal, lalu kembalikan salah satu trueatau false. Jika tidak, setiap kali Anda menggunakannya, Anda perlu memeriksa kode kembali sebelum melakukan hal lain, dan menemukan cara untuk menanganinya. Itu berarti Anda harus memeriksa dokumen untuk melihat apakah suatu fungsi benar-benar melakukan apa yang dikatakan namanya, dan itu akan menjadi bencana bagi keterbacaan.

David Thornley
sumber
2

Idenya cukup bermanfaat. Ada seluruh bidang yang ditujukan untuk menangani ketidakpastian yang disebut Fuzzy Logic .

Untungnya bagi kami programmer, Anda dapat menerapkan logika fuzzy dengan fitur bahasa standar.

Misalnya, dalam kasus yang Anda berikan, informasi yang tidak pasti mudah ditentukan dengan bertanya kepada pengguna. Jadi enum tri-state seperti yang Anda gambarkan akan bekerja dengan baik.

Ada segala macam cara lain untuk menjadi tidak pasti. Pertanyaan-pertanyaan tersebut meliputi:

  • Akankah besok hujan? Itu belum terjadi, jadi tidak ada yang bisa tahu - tetapi Anda dapat membuat tebakan yang berpendidikan dan memberikan probabilitas.
  • Apakah ada kehidupan multiseluler di sebuah planet di tata surya bintang Beta Pictoris? Ia memiliki jawaban ya-atau-tidak yang pasti, tetapi saat ini kami tidak dapat mengatakannya.

Banyak dari pertanyaan-pertanyaan itu dapat diatasi dengan menggunakan probabilitas dalam kisaran 0,0 (salah) hingga 1,0 (benar), dan menerapkan matematika floating point.

Seorang ahli kimia komputasi dan ilmuwan komputer bernama David E. Shaw menerapkan hal semacam ini ke Wall Street dan sekarang bernilai sekitar $ 2,5 miliar. Jadi ya, ini berguna. :-)

Bob Murphy
sumber
1

Bertahun-tahun yang lalu saya bermain dengan beberapa algoritma yang keluar untuk menetapkan kepercayaan pada nilai-nilai. Menyenangkan. Pada akhirnya apa yang saya peroleh dari itu adalah bahwa boolean sering dibuat-buat. Benar-benar harus trilean nilai true / false / lainnya. Dalam eksperimen yang sepertinya mengarah pada kode "terbaik" untuk saya pada saat itu. Saya sejak menyerah dan melakukan apa yang dilakukan orang lain, sambil berpikir secara internal betapa lebih sederhana itu BISA jika kita berhenti melakukan hal-hal dengan cara lama yang sama ... :-)

Brian Knoblauch
sumber
0

Pernyataan Case atau Switch akan bekerja dengan baik untuk ini, dengan menggunakan bilangan bulat untuk menangani switch secara sewenang-wenang.

Juga, di Ruby, sementara 'nil' kembali sebagai false dalam beberapa keadaan, jika Anda menggunakan operator kesetaraan, nil == falsekembali false, sehingga Anda bisa menggunakan ruby niluntuk menangani logika ternary.

philosodad
sumber
0

Opsi lain dalam kasus Anda mungkin untuk membalikkan kontrol dengan menerapkan prinsip "katakan jangan tanya" dan mengubahnya menjadi (maaf tentang kata dewasa, penyumbatan otak):

user.isAdult(new OnlyAllowAdultsToLogin())

di mana OnlyAllowAdultsToLoginStrategymengimplementasikan antarmuka:

interface UserAdultnessPolicy
{
   void userIsAdult();
   void userIsChild();
   void userAdultnessIsUnknown();
}
flamingpenguin
sumber
Apa yang void userIsAdult()harus dilakukan Mungkin maksudmu bool userIsAdult()?
Timwi
0

Anak saya bertanya kepada saya bagaimana menerapkan tes yang mirip ini secara efisien. Bendera yang diuji hanya benar / salah, tetapi korek api memiliki tiga status (Pasti benar, pasti salah, atau saya tidak peduli). Tentu saja ini dapat diimplementasikan dengan struktur data 2bit dan sedikit memutar-mutar, tetapi kode semacam itu benar-benar perlu dikomentari karena tujuannya tidak mudah untuk dilihat hanya dengan melihat kode.

Omega Centauri
sumber
0

C telah menerapkan fitur ini di sebagian besar fungsi perpustakaan. mis. strcmp membandingkan 2 string dan mengembalikan 0 jika mereka sama, 1 (yaitu bilangan bulat positif) jika yang pertama 'lebih besar' dari yang ke-2, dan -1 (yaitu bilangan negatif apa pun) jika yang kedua lebih besar dari yang pertama .

Pendekatan yang sama dapat digunakan di tempat lain, + / 0 / - sebagai tri-state Anda. Ini juga memungkinkan Anda melakukan logika boolean pada nilai-nilai jika Anda tahu 0 jika salah dan nilai lainnya benar.

gbjbaanb
sumber
0

Untuk C ++, Boost sebenarnya mengimplementasikan Tribool yang dideskripsikan sebagai:

Kelas tribool bertindak seperti tipe bool bawaan, tetapi untuk logika boolean 3-negara. Tiga negara adalah benar, salah, dan tak tentu, di mana dua negara pertama setara dengan orang-orang dari tipe bool C ++ dan negara terakhir mewakili nilai boolean yang tidak diketahui (yang mungkin benar atau salah, kita tidak tahu).

Matthieu
sumber
-1

Kotak centang VB6 memiliki kemampuan ini. Nilai kotak centang bisa 0 = tidak aktif, 1 = aktif, 2 = berwarna abu-abu

Dave
sumber