Mengapa sebagian besar bahasa imperatif / OO “terkenal” memungkinkan akses tidak terkendali ke tipe yang dapat mewakili nilai 'tidak ada'?

29

Saya telah membaca tentang kenyamanan (bukan) memiliki nullalih-alih (misalnya) Maybe. Setelah membaca artikel ini , saya yakin akan jauh lebih baik menggunakanMaybe (atau yang serupa). Namun, saya terkejut melihat bahwa semua "terkenal" imperatif atau bahasa pemrograman berorientasi objek masih menggunakan null(yang memungkinkan akses tidak dicentang ke jenis yang dapat mewakili nilai 'tidak ada'), dan yang Maybesebagian besar digunakan dalam bahasa pemrograman fungsional.

Sebagai contoh, lihat kode C # berikut:

void doSomething(string username)
{
    // Check that username is not null
    // Do something
}

Ada yang baunya tidak enak di sini ... Mengapa kita harus memeriksa jika argumennya nol? Bukankah kita seharusnya mengasumsikan bahwa setiap variabel berisi referensi ke suatu objek? Seperti yang Anda lihat, masalahnya adalah bahwa menurut definisi, hampir semua variabel dapat berisi referensi nol. Bagaimana jika kita dapat memutuskan variabel mana yang "nullable" dan mana yang tidak? Itu akan menyelamatkan kita dari banyak upaya saat debugging dan mencari "NullReferenceException". Bayangkan, secara default, tidak ada tipe yang bisa berisi referensi nol . Alih-alih itu, Anda akan menyatakan secara eksplisit bahwa variabel dapat berisi referensi nol , hanya jika Anda benar-benar membutuhkannya. Itulah ide di balik Maybe. Jika Anda memiliki fungsi yang dalam beberapa kasus gagal (misalnya pembagian dengan nol), Anda dapat mengembalikan aMaybe<int>, menyatakan secara eksplisit bahwa hasilnya mungkin int, tetapi juga bukan apa-apa! Ini adalah salah satu alasan untuk memilih Mungkin daripada nol. Jika Anda tertarik pada lebih banyak contoh, maka saya sarankan untuk membaca artikel ini .

Faktanya adalah bahwa, meskipun ada kelemahan membuat sebagian besar tipe dapat dibatalkan secara default, sebagian besar bahasa pemrograman OO benar-benar melakukannya. Itu sebabnya saya bertanya-tanya tentang:

  • Argumen seperti apa yang harus Anda terapkan nulldalam bahasa pemrograman Anda, bukan Maybe? Apakah ada alasan atau hanya "bagasi bersejarah"?

Harap pastikan Anda memahami perbedaan antara nol dan Mungkin sebelum menjawab pertanyaan ini.

aochagavia
sumber
3
Saya sarankan membaca tentang Tony Hoare , khususnya kesalahan miliaran dolar.
Oded
2
Nah, itu dia alasan. Dan hasil yang disayangkan adalah bahwa itu adalah kesalahan yang disalin ke sebagian besar bahasa yang mengikuti, hingga hari ini. Ada yang bahasa mana nullatau konsep tidak ada (IIRC Haskell adalah salah satu contohnya).
Oded
9
Bagasi historis bukanlah sesuatu yang bisa diremehkan. Dan ingat bahwa OS yang dibangun di atas ini ditulis dalam bahasa yang sudah lama ada nulldi dalamnya. Tidak mudah menjatuhkannya begitu saja.
Oded
3
Saya pikir Anda harus menjelaskan konsep Mungkin alih-alih memposting tautan.
JeffO
1
@ GlenH7 Strings dalam C # adalah nilai referensi (mereka bisa nol). Saya tahu bahwa int adalah nilai primitif, tetapi bermanfaat untuk menunjukkan penggunaan mungkin.
aochagavia

Jawaban:

15

Saya percaya ini adalah bawaan sejarah.

Bahasa yang paling menonjol dan tertua nulladalah C dan C ++. Tapi di sini, nullmemang masuk akal. Pointer masih cukup numerik dan konsep tingkat rendah. Dan bagaimana orang lain berkata, dalam pola pikir programmer C dan C ++, harus secara eksplisit mengatakan bahwa pointer nullitu tidak masuk akal.

Baris kedua adalah Java. Mempertimbangkan pengembang Java sedang berusaha mendekati C ++, sehingga mereka dapat membuat transisi dari C ++ ke Java lebih sederhana, mereka mungkin tidak ingin mengacaukan konsep inti bahasa tersebut. Selain itu, penerapan eksplisit nullakan membutuhkan lebih banyak upaya, karena Anda harus memeriksa apakah referensi non-nol benar-benar ditetapkan dengan benar setelah inisialisasi.

Semua bahasa lain sama dengan Java. Mereka biasanya menyalin cara C ++ atau Java melakukannya, dan mempertimbangkan bagaimana konsep inti nulldari jenis referensi implisit , menjadi sangat sulit untuk merancang bahasa yang menggunakan eksplisit null.

Euforia
sumber
"Mereka mungkin tidak ingin mengacaukan konsep inti bahasa tersebut." Mereka sudah sepenuhnya menghapus pointer, juga menghapus nulltidak akan menjadi perubahan besar, saya pikir.
svick
2
@vick Untuk Java, referensi adalah pengganti pointer. Dan dalam banyak kasus, pointer dalam C ++ digunakan dengan cara yang sama seperti apa yang dilakukan referensi Java. Beberapa orang bahkan mengklaim bahwa Java memiliki pointer ( programmers.stackexchange.com/questions/207196/... )
Euphoric
Saya telah menandai ini sebagai jawaban yang benar. Saya ingin membatalkannya tetapi saya tidak memiliki reputasi yang cukup.
aochagavia
1
Setuju. Perhatikan bahwa dalam C ++ (tidak seperti Java dan C), menjadi null-bisa adalah pengecualian. std::stringtidak mungkin null. int&tidak mungkin null. Sebuah int*kaleng, dan C ++ memungkinkan akses yang tidak dicentang untuk itu karena dua alasan: 1. karena C lakukan dan 2. karena Anda seharusnya memahami apa yang Anda lakukan ketika menggunakan pointer mentah di C ++.
MSalters
@MSalters: Jika suatu tipe tidak memiliki nilai default bit-copyable, maka membuat sebuah array dari tipe itu akan memerlukan memanggil konstruktor untuk setiap elemennya sebelum mengizinkan akses ke array itu sendiri. Ini mungkin memerlukan pekerjaan yang tidak berguna (jika beberapa atau semua elemen akan ditimpa sebelum dibaca), dapat menimbulkan komplikasi jika konstruktor untuk elemen selanjutnya gagal setelah elemen sebelumnya telah dibangun, dan mungkin akhirnya tidak benar-benar menyelesaikan banyak hal (jika nilai yang tepat untuk beberapa elemen array tidak dapat ditentukan tanpa membaca yang lain).
supercat
15

Sebenarnya, nullitu ide bagus. Diberikan pointer, kami ingin menunjukkan bahwa pointer ini tidak mereferensikan nilai yang valid. Jadi kami mengambil satu lokasi memori, menyatakan itu tidak valid, dan tetap pada konvensi itu (konvensi yang kadang-kadang diberlakukan dengan segfault). Sekarang setiap kali saya memiliki pointer saya dapat memeriksa apakah itu berisi Nothing( ptr == null) atau Some(value)( ptr != null, value = *ptr). Saya ingin Anda mengerti bahwa ini setara dengan Maybetipe.

Masalah dengan ini adalah:

  1. Dalam banyak bahasa, sistem tipe tidak membantu di sini untuk menjamin referensi yang tidak nol.

    Ini adalah muatan historis, karena banyak bahasa arus utama imperatif atau OOP hanya memiliki kemajuan tambahan dalam sistem tipenya jika dibandingkan dengan pendahulunya. Perubahan kecil memiliki keuntungan bahwa bahasa baru lebih mudah dipelajari. C # adalah bahasa utama yang telah memperkenalkan alat tingkat bahasa untuk menangani nulls dengan lebih baik.

  2. Desainer API mungkin kembali nullpada kegagalan, tetapi tidak merujuk pada hal yang sebenarnya pada kesuksesan. Seringkali, benda (tanpa referensi) dikembalikan secara langsung. Perataan satu tingkat penunjuk ini memungkinkan untuk digunakan nullsebagai nilai.

    Ini hanya kemalasan di sisi desainer dan tidak dapat membantu tanpa menegakkan sarang yang tepat dengan sistem tipe yang tepat. Beberapa orang mungkin juga mencoba untuk membenarkan ini dengan pertimbangan kinerja, atau dengan adanya pemeriksaan opsional (koleksi mungkin kembali nullatau barang itu sendiri, tetapi juga menyediakan containsmetode).

  3. Di Haskell ada pandangan rapi ke Maybetipe sebagai monad. Ini membuatnya lebih mudah untuk menyusun transformasi pada nilai yang terkandung.

    Di sisi lain, bahasa tingkat rendah seperti C nyaris tidak memperlakukan array sebagai tipe terpisah, jadi saya tidak yakin apa yang kami harapkan. Dalam bahasa OOP dengan polimorfisme parameter, Maybetipe yang diperiksa runtime agak sepele untuk diterapkan.

amon
sumber
“C # mengambil langkah dari referensi nol.” Langkah apa itu? Saya belum melihat hal seperti itu dalam perubahan bahasa. Atau maksud Anda hanya bahwa perpustakaan umum menggunakan nullkurang dari yang mereka lakukan di masa lalu?
svick
@vick Frase buruk di pihak saya. “ C # adalah bahasa utama yang telah memperkenalkan alat bahasa tingkat ke pegangan yang lebih baik nulls ” - Saya berbicara tentang Nullablejenis dan ??operator yang default. Itu tidak memecahkan masalah saat ini di hadapan kode warisan, tetapi merupakan langkah menuju masa depan yang lebih baik.
amon
Saya setuju dengan Anda. Saya akan memilih jawaban Anda tetapi saya tidak memiliki reputasi yang cukup :( Namun, Nullable hanya berfungsi untuk tipe primitif. Jadi itu hanya langkah kecil.
aochagavia
1
@svick Nullable tidak ada hubungannya dengan ini. Kita berbicara tentang semua tipe referensi yang secara implisit memungkinkan nilai nol, daripada meminta programmer untuk mendefinisikannya secara eksplisit. Dan Nullable hanya bisa digunakan pada tipe nilai.
Euforia
@ Euforia Saya pikir komentar Anda dimaksudkan sebagai balasan untuk Amon, saya tidak menyebutkan Nullable.
svick
9

Pemahaman saya adalah nullkonstruksi yang diperlukan untuk abstrak bahasa pemrograman di luar perakitan. 1 Programmer membutuhkan kemampuan untuk menunjukkan bahwa pointer atau nilai register adalah not a valid valuedan nullmenjadi istilah umum untuk makna itu.

Memperkuat poin yang nullhanya konvensi untuk mewakili konsep, nilai aktual untuk nulldapat / dapat bervariasi berdasarkan bahasa dan platform pemrograman.

Jika Anda merancang bahasa baru dan ingin menghindari nulltetapi menggunakan maybesebagai gantinya, maka saya akan mendorong istilah yang lebih deskriptif seperti not a valid valueatau navvuntuk menunjukkan maksudnya. Tetapi nama yang tidak bernilai itu adalah konsep yang terpisah dari apakah Anda harus membiarkan nilai yang tidak ada itu ada dalam bahasa Anda.

Sebelum Anda dapat memutuskan salah satu dari dua poin tersebut, Anda perlu menentukan apa arti dari maybearti bagi sistem Anda. Anda mungkin menemukan itu hanya mengubah nama nullmakna not a valid valueatau Anda mungkin menemukan itu memiliki semantik yang berbeda untuk bahasa Anda.

Demikian juga, keputusan apakah akan memeriksa akses terhadap nullakses atau referensi adalah keputusan desain lain dari bahasa Anda.

Untuk memberikan sedikit sejarah, Cmemiliki asumsi implisit bahwa programmer memahami apa yang mereka coba lakukan ketika memanipulasi memori. Karena itu adalah abstraksi yang unggul untuk perakitan dan bahasa-bahasa penting yang mendahuluinya, saya berani mengatakan bahwa pemikiran untuk melindungi para programmer dari referensi yang salah tidak muncul di benak mereka.

Saya percaya bahwa beberapa kompiler atau alat tambahan mereka dapat memberikan ukuran pemeriksaan terhadap akses pointer yang tidak valid. Jadi orang lain telah mencatat masalah potensial ini dan mengambil langkah-langkah untuk melindunginya.

Apakah Anda mengizinkan atau tidak tergantung pada apa yang Anda ingin capai dalam bahasa Anda dan tingkat tanggung jawab apa yang ingin Anda sampaikan kepada pengguna bahasa Anda. Ini juga tergantung pada kemampuan Anda membuat kompiler untuk membatasi jenis perilaku itu.

Jadi untuk menjawab pertanyaan Anda:

  1. "Argumen seperti apa ..." - Yah, itu tergantung pada apa yang Anda ingin bahasa itu lakukan. Jika Anda ingin mensimulasikan akses bare-metal maka Anda mungkin ingin mengizinkannya.

  2. "Apakah ini hanya bagasi bersejarah?" Mungkin, mungkin juga tidak. nulltentu memiliki / memiliki arti untuk sejumlah bahasa dan membantu mengarahkan ekspresi bahasa-bahasa tersebut. Preseden historis mungkin telah memengaruhi bahasa yang lebih baru dan memungkinkannya nulltetapi agak berlebihan untuk melambaikan tangan Anda dan mendeklarasikan konsep bagasi historis yang tidak berguna.


1 Lihat artikel Wikipedia ini meskipun kredit diberikan untuk Hoare untuk nilai-nilai nol dan bahasa berorientasi objek. Saya percaya bahasa imperatif berkembang di sepanjang silsilah keluarga yang berbeda dari Algol.


sumber
Intinya adalah bahwa sebagian besar variabel dalam, katakanlah, C # atau Java, dapat diberi referensi nol. Sepertinya akan jauh lebih baik untuk menetapkan referensi nol hanya untuk objek yang secara eksplisit menunjukkan bahwa "Mungkin" tidak ada referensi. Jadi, pertanyaan saya adalah tentang "konsep" nol, dan bukan kata.
aochagavia
2
“Referensi penunjuk kosong dapat muncul sebagai kesalahan selama proses kompilasi” Kompiler mana yang dapat melakukannya?
svick
Agar benar-benar adil, Anda tidak pernah menetapkan referensi nol ke objek ... referensi ke objek tidak ada (referensi menunjuk ke ketiadaan (0x000000000), yang menurut definisi null).
mgw854
Kutipan C99 spec berbicara tentang karakter nol , bukan pointer nol , itu adalah dua konsep yang sangat berbeda.
svick
2
@ GlenH7 Itu tidak melakukan itu untuk saya. Kode object o = null; o.ToString();mengkompilasi dengan baik bagi saya, tanpa kesalahan atau peringatan di VS2012. ReSharper mengeluhkan hal itu, tapi itu bukan kompiler.
svick
7

Jika Anda melihat contoh di artikel yang Anda kutip, sebagian besar waktu menggunakan Maybetidak mempersingkat kode. Itu tidak meniadakan kebutuhan untuk memeriksa Nothing. Satu-satunya perbedaan adalah itu mengingatkan Anda untuk melakukannya melalui sistem tipe.

Catatan, saya katakan "ingatkan," bukan paksaan. Pemrogram malas. Jika seorang programmer yakin suatu nilai tidak mungkin Nothing, mereka akan melakukan dereferensi Maybetanpa memeriksanya, seperti halnya mereka men-decereer null pointer sekarang. Hasil akhirnya adalah Anda mengubah pengecualian penunjuk nol menjadi pengecualian "mungkin kosong".

Prinsip yang sama dari sifat manusia berlaku di bidang lain di mana bahasa pemrograman mencoba memaksa pemrogram untuk melakukan sesuatu. Sebagai contoh, perancang Java mencoba memaksa orang untuk menangani sebagian besar pengecualian, yang menghasilkan banyak pelat baja yang mengabaikan secara diam-diam atau menyebarkan pengecualian secara membuta.

Apa yang membuat Maybeitu menyenangkan adalah ketika banyak keputusan dibuat melalui pencocokan pola dan polimorfisme alih-alih pemeriksaan eksplisit. Misalnya, Anda dapat membuat fungsi terpisah processData(Some<T>)dan processData(Nothing<T>)yang tidak dapat Anda lakukan null. Anda secara otomatis memindahkan penanganan kesalahan Anda ke fungsi yang terpisah, yang sangat diinginkan dalam pemrograman fungsional di mana fungsi diedarkan dan dievaluasi dengan malas daripada selalu dipanggil secara top-down. Dalam OOP, cara yang lebih disukai untuk memisahkan kode penanganan kesalahan Anda adalah dengan pengecualian.

Karl Bielefeldt
sumber
Apakah Anda pikir itu akan menjadi fitur yang diinginkan dalam bahasa OO baru?
aochagavia
Anda dapat menerapkannya sendiri jika Anda ingin mendapatkan manfaat polimorfisme. Satu-satunya hal yang Anda perlukan untuk dukungan bahasa adalah tidak dapat dibatalkan. Saya akan senang melihat cara untuk menentukan itu untuk Anda sendiri, mirip dengan const, tetapi menjadikannya opsional. Beberapa jenis kode tingkat rendah, seperti daftar yang ditautkan misalnya, akan sangat menjengkelkan untuk diterapkan dengan objek yang tidak dapat dibatalkan.
Karl Bielefeldt
2
Anda tidak perlu memeriksa dengan tipe Maybe. Jenis Maybe adalah monad sehingga harus memiliki fungsi map :: Maybe a -> (a -> b) dan bind :: Maybe a -> (a -> Maybe b)didefinisikan di atasnya, sehingga Anda dapat melanjutkan dan utas perhitungan lebih lanjut untuk sebagian besar dengan menyusun kembali menggunakan pernyataan if else. Dan getValueOrDefault :: Maybe a -> (() -> a) -> amemungkinkan Anda untuk menangani kasing kosong. Ini jauh lebih elegan daripada pencocokan pola Maybe asecara eksplisit.
DetriusXii
1

Maybeadalah cara berpikir masalah yang sangat fungsional - ada sesuatu, dan itu mungkin atau mungkin tidak memiliki nilai yang didefinisikan. Namun, dalam pengertian berorientasi objek, kami mengganti gagasan tentang suatu hal (tidak peduli apakah itu memiliki nilai atau tidak) dengan suatu objek. Jelas, suatu objek memiliki nilai. Jika tidak, kita mengatakan objeknya null, tetapi yang kita maksud sebenarnya adalah bahwa tidak ada objek sama sekali. Referensi yang kita miliki ke objek tidak menunjukkan apa-apa. Menerjemahkan Maybeke dalam konsep OO tidak melakukan apa-apa novel - pada kenyataannya, itu hanya membuat kode lebih berantakan. Anda masih harus memiliki referensi nol untuk nilaiMaybe<T>. Anda masih harus melakukan pemeriksaan nol (pada kenyataannya, Anda harus melakukan lebih banyak pemeriksaan nol, mengacaukan kode Anda), bahkan jika sekarang disebut "mungkin cek". Tentu, Anda akan menulis kode yang lebih kuat seperti yang diklaim oleh penulis, tetapi saya berpendapat bahwa ini hanya masalahnya karena Anda telah membuat bahasanya jauh lebih abstrak dan tumpul, membutuhkan tingkat pekerjaan yang tidak perlu dalam kebanyakan kasus. Saya rela mengambil NullReferenceException sesekali daripada berurusan dengan kode spaghetti melakukan pemeriksaan Mungkin setiap kali saya mengakses variabel baru.

mgw854
sumber
2
Saya pikir itu akan menyebabkan kurang dari nol pemeriksaan, karena Anda hanya perlu memeriksa apakah Anda melihat <T> Mungkin dan tidak perlu khawatir tentang sisa jenis.
aochagavia
1
@svick Maybe<T>harus mengizinkan nullsebagai nilai, karena nilainya mungkin tidak ada. Jika saya punya Maybe<MyClass>, dan tidak memiliki nilai, bidang nilai harus berisi referensi nol. Tidak ada hal lain untuk itu yang benar-benar aman.
mgw854
1
@ mgw854 Tentu ada. Dalam bahasa OO, Maybebisa berupa kelas abstrak, dengan dua kelas yang mewarisi darinya: Some(yang memang memiliki bidang untuk nilai) dan None(yang tidak memiliki bidang itu). Dengan begitu, nilainya tidak pernah null.
svick
6
Dengan "not-nullability" secara default, dan Mungkin <T> Anda bisa yakin bahwa beberapa variabel selalu berisi objek. Yaitu, semua variabel yang tidak Mungkin <T>
aochagavia
3
@ mgw854 Inti dari perubahan ini adalah peningkatan daya ekspresif untuk pengembang. Saat ini, pengembang selalu harus berasumsi, bahwa referensi atau pointer bisa nol dan perlu melakukan pengecekan untuk memastikan ada nilai yang dapat digunakan. Dengan menerapkan perubahan ini, Anda memberi kekuatan pengembang untuk mengatakan bahwa ia benar-benar membutuhkan nilai yang valid dan memiliki pemeriksaan kompiler untuk memastikan nilai yang valid telah diteruskan. Tetapi masih memberikan opsi pengembang, untuk memilih dan tidak memberikan nilai.
Euforia
1

Konsep nulldapat dengan mudah ditelusuri kembali ke C tetapi tidak di situlah masalahnya.

Bahasa pilihan sehari-hari saya adalah C # dan saya akan tetap nulldengan satu perbedaan. C # memiliki dua jenis tipe, nilai dan referensi . Nilai tidak pernah bisa null, tetapi ada saatnya saya ingin bisa menyatakan bahwa tidak ada nilai yang baik-baik saja. Untuk melakukan ini C # menggunakan Nullabletipe sehingga intakan menjadi nilai dan int?nilai nullable. Ini adalah bagaimana saya pikir tipe referensi harus bekerja juga.

Lihat juga: Referensi kosong mungkin bukan kesalahan :

Referensi kosong sangat membantu dan terkadang sangat diperlukan (pertimbangkan berapa banyak masalah jika Anda dapat atau tidak mengembalikan string dalam C ++). Kesalahannya sebenarnya bukan pada keberadaan pointer nol, tetapi pada bagaimana sistem jenis menangani mereka. Sayangnya sebagian besar bahasa (C ++, Java, C #) tidak menanganinya dengan benar.

Daniel Little
sumber
0

Saya pikir ini karena pemrograman fungsional lebih memperhatikan tipe , terutama tipe yang menggabungkan tipe lain (tuple, fungsi sebagai tipe kelas satu, monad, dll.) Daripada pemrograman berorientasi objek (atau paling tidak pada awalnya memang demikian).

Versi modern dari bahasa pemrograman yang saya pikir Anda bicarakan (C ++, C #, Java) semuanya didasarkan pada bahasa yang tidak memiliki bentuk pemrograman generik (C, C # 1.0, Java 1). Tanpa itu, Anda masih dapat memanggang beberapa jenis antara objek nullable dan non-nullable ke dalam bahasa (seperti referensi C ++, yang tidak bisa null, tetapi juga terbatas), tetapi itu jauh kurang alami.

svick
sumber
Saya pikir dalam hal pemrograman fungsional, ini adalah kasus FP tidak memiliki jenis referensi atau pointer. Dalam FP semuanya adalah nilai. Dan jika Anda memiliki tipe pointer, mudah untuk mengatakan "pointer to nothing".
Euforia
0

Saya pikir alasan mendasar adalah bahwa relatif sedikit pemeriksaan nol diperlukan untuk membuat program "aman" terhadap korupsi data. Jika suatu program mencoba menggunakan konten elemen array atau lokasi penyimpanan lain yang seharusnya ditulis dengan referensi yang valid tetapi tidak, hasil kasus terbaik adalah pengecualian yang akan dibuang. Idealnya, pengecualian akan menunjukkan dengan tepat di mana masalah terjadi, tetapi yang penting adalah beberapa jenis pengecualian dilemparkan sebelum referensi nol disimpan di suatu tempat yang dapat menyebabkan korupsi data. Kecuali suatu metode menyimpan suatu objek tanpa mencoba menggunakannya terlebih dahulu, suatu upaya untuk menggunakan suatu objek akan - dengan sendirinya - merupakan semacam "pemeriksaan kosong".

Jika seseorang ingin memastikan bahwa referensi nol yang muncul di tempat yang seharusnya tidak menyebabkan pengecualian khusus selain NullReferenceException, sering kali perlu menyertakan cek nol di semua tempat. Di sisi lain, hanya memastikan bahwa beberapa pengecualian akan terjadi sebelum referensi nol dapat menyebabkan "kerusakan" di luar apa pun yang telah dilakukan akan sering memerlukan tes yang relatif sedikit - pengujian umumnya hanya diperlukan dalam kasus di mana suatu objek akan menyimpan referensi tanpa mencoba menggunakannya, dan baik referensi nol akan menimpa yang valid, atau akan menyebabkan kode lain salah menafsirkan aspek lain dari keadaan program. Situasi seperti itu ada, tetapi tidak terlalu umum; kebanyakan referensi nol yang tidak disengaja akan tertangkap dengan sangat cepatapakah orang memeriksa mereka atau tidak .

supercat
sumber
posting ini agak sulit dibaca (dinding teks). Maukah Anda mengeditnya menjadi bentuk yang lebih baik?
nyamuk
1
@gnat: Apakah itu lebih baik?
supercat
0

" Maybe," seperti yang tertulis, adalah konstruk tingkat yang lebih tinggi daripada nol. Menggunakan lebih banyak kata untuk mendefinisikannya, Mungkin adalah, "pointer ke salah satu hal, atau pointer ke tidak ada, tetapi kompiler belum diberi informasi yang cukup untuk menentukan yang mana." Ini memaksa Anda untuk secara eksplisit memeriksa setiap nilai secara konstan, kecuali jika Anda membangun spesifikasi kompiler yang cukup pintar untuk mengikuti kode yang Anda tulis.

Anda dapat membuat implementasi Maybe dengan bahasa yang memiliki null dengan mudah. C ++ memiliki satu dalam bentuk boost::optional<T>. Membuat yang setara dengan null dengan Maybe sangat sulit. Secara khusus, jika saya memiliki Maybe<Just<T>>, saya tidak dapat menetapkannya ke nol (karena konsep seperti itu tidak ada), sedangkan T**dalam bahasa dengan nol sangat mudah untuk menetapkan ke nol. Ini memaksa seseorang untuk menggunakan Maybe<Maybe<T>>, yang benar-benar valid, tetapi akan memaksa Anda untuk melakukan lebih banyak pemeriksaan untuk menggunakan objek itu.

Beberapa bahasa fungsional menggunakan Mungkin karena null memerlukan perilaku yang tidak terdefinisi atau penanganan perkecualian, yang keduanya tidak merupakan konsep yang mudah untuk dipetakan ke dalam sintaksis bahasa fungsional. Mungkin mengisi peran jauh lebih baik dalam situasi fungsional seperti itu, tetapi dalam bahasa prosedural, null adalah raja. Ini bukan masalah benar dan salah, hanya masalah apa yang membuatnya lebih mudah untuk memberitahu komputer untuk melakukan apa yang Anda inginkan.

Cort Ammon - Pulihkan Monica
sumber