“Mudah dipikirkan” - apa artinya itu? [Tutup]

49

Saya telah mendengar banyak kali ketika pengembang lain menggunakan frase itu untuk "beriklan" beberapa pola atau mengembangkan praktik terbaik. Sebagian besar waktu kalimat ini digunakan ketika Anda berbicara tentang manfaat pemrograman fungsional.

Ungkapan "Easy to reason about" telah digunakan apa adanya, tanpa penjelasan atau contoh kode. Jadi bagi saya itu menjadi seperti kata "buzz" berikutnya, yang lebih banyak digunakan pengembang "berpengalaman" dalam pembicaraan mereka.

Pertanyaan: Bisakah Anda memberikan beberapa contoh "Tidak mudah untuk beralasan", sehingga dapat dibandingkan dengan contoh "Mudah untuk beralasan tentang"?

Fabio
sumber
4
@ MartinMaat frase yang lebih tepat yang banyak digunakan adalah penalaran yang sama, saya akan menyarankan bahwa ini adalah apa yang Fabio cari
jk.
3
Saya suka menggunakan frasa "muatan kognitif" untuk hal semacam ini.
Baldrickk
16
Tahukah Anda apa alasan program itu ?
Bergi
5
Dalam arti non-formal, saya menggunakan ini berarti solusi cukup sederhana untuk memahami (umumnya) apa hasilnya untuk setiap input yang diberikan tanpa mengujinya. Ini berarti bahwa untuk setiap set input, hasilnya tidak akan mengejutkan. Solusi yang memiliki kasus sudut tidak jelas, misalnya, sulit dipikirkan. Terutama saya menggunakan ini sehubungan dengan ketahanan.
JimmyJames
7
Saya sangat bersalah karena sering menggunakan "alasan yang lebih mudah untuk dipikirkan"; Namun saya perhatikan bahwa saya mencoba berhati-hati untuk mengatakan komparatif lebih mudah daripada yang absolut mudah . Ada satu hari dalam hidup saya ketika saya dapat bernalar tentang tidak ada perangkat lunak sama sekali, jadi itu tidak mudah pada hari itu; menjadi mudah hanya dengan menghabiskan banyak waktu dan usaha. Untuk mengatakan bahwa setiap masalah pemrograman itu mudah adalah mengambil sikap merendahkan terhadap siapa pun yang mungkin belum (belum) merasa mudah. Mengatakan bahwa satu model lebih mudah daripada yang lain berarti mengatakan bahwa ada lebih sedikit konsep yang terlibat, lebih sedikit bagian yang bergerak, dan sebagainya.
Eric Lippert

Jawaban:

58

Dalam benak saya, frasa "mudah beralasan tentang", merujuk pada kode yang mudah "dieksekusi di kepala Anda".

Ketika melihat sepotong kode, jika pendek, ditulis dengan jelas, dengan nama baik dan mutasi nilai minimal, maka secara mental mengerjakan apa yang dilakukan kode itu adalah tugas yang (relatif) mudah.

Sepotong kode panjang dengan nama yang buruk, variabel yang terus-menerus mengubah nilai dan percabangan berbelit-belit biasanya akan membutuhkan misalnya pena dan selembar kertas untuk membantu melacak keadaan saat ini. Karenanya kode seperti itu tidak dapat dengan mudah dikerjakan hanya di kepala Anda, Jadi kode tersebut tidak mudah dipikirkan.

David Arno
sumber
29
Dengan sedikit peringatan bahwa tidak peduli seberapa baik Anda menamai variabel Anda, sebuah program yang mencoba untuk menyangkal dugaan Goldbach secara inheren sulit untuk "dieksekusi", di kepala Anda atau di tempat lain. Tetapi masih mudah untuk berargumentasi, dalam arti mudah meyakinkan diri sendiri bahwa jika ia mengklaim telah menemukan contoh tandingan maka itu mengatakan yang sebenarnya ;-)
Steve Jessop
4
Saya tidak akan pernah ingin mengeksekusi kode di kepala saya. Bagi saya, itu akan menjadi pertunjukan pamungkas "tidak mudah dipikirkan." Saya ingin dapat membuat pernyataan prediktif tentang apa yang akan dilakukan komputer tanpa menjalankannya. Kode yang "mudah untuk diartikan" adalah kode yang tidak harus dijalankan di kepala Anda, itu bisa dijadikan alasan.
Cort Ammon
1
Bagaimana seseorang dapat menjawab pertanyaan tentang alasan tentang kode tanpa menyebutkan verifikasi formal ? Jawaban ini menunjukkan bahwa alasan tentang kode bersifat informal dan ad-hoc. ini bukan, biasanya dilakukan dengan sangat hati-hati dan pendekatan matematika. Ada sifat-sifat matematika tertentu yang membuat kode "mudah dipikirkan" dalam arti obyektif (fungsi murni, untuk memberikan contoh yang sangat mudah). nama variabel tidak ada hubungannya dengan betapa mudahnya untuk "alasan" tentang kode, setidaknya tidak dalam arti formal.
Polygnome
3
@ Polygnome Penalaran tentang kode biasanya tidak dilakukan dengan sangat hati-hati dan pendekatan matematika. Ketika saya menulis ini, orang-orang yang beralasan tentang kode secara informal melebihi jumlah pengamat matematika oleh jutaan menjadi satu, setidaknya, atau begitulah menurut saya.
Kaz
2
@ Polygnome "Code easy to reason about" almost exclusively alludes to its mathematical properties and formal verification- yang kira-kira terdengar seperti jawaban atas pertanyaan. Anda mungkin ingin memposting itu sebagai jawaban alih-alih tidak setuju tentang apa jawaban (subyektif) dalam komentar.
Dukeling
47

Mekanisme atau sepotong kode mudah dipikirkan tentang kapan Anda perlu mempertimbangkan beberapa hal untuk memprediksi apa yang akan dilakukannya, dan hal-hal yang perlu Anda perhitungkan mudah tersedia.

Fungsi sebenarnya tanpa efek samping dan tidak ada keadaan mudah dipikirkan karena output sepenuhnya ditentukan oleh input, yang ada di sana dalam parameter.

Sebaliknya, objek dengan keadaan jauh lebih sulit untuk dipikirkan, karena Anda harus memperhitungkan keadaan apa objek tersebut ketika sebuah metode dipanggil, yang berarti Anda harus berpikir tentang situasi lain yang dapat mengarah pada objek lain yang berada dalam suatu objek. negara bagian tertentu.

Yang lebih buruk lagi adalah variabel global: untuk alasan tentang kode yang membaca variabel global, Anda perlu memahami di mana dalam kode Anda variabel itu dapat diatur dan mengapa - dan bahkan mungkin tidak mudah untuk menemukan semua tempat itu.

Salah satu hal tersulit untuk dipikirkan adalah pemrograman multithreaded dengan status bersama, karena Anda tidak hanya memiliki status, Anda memiliki beberapa utas mengubahnya sekaligus, jadi untuk alasan tentang apa yang dilakukan sepotong kode ketika dijalankan oleh satu utas Anda harus memungkinkan untuk kemungkinan bahwa pada setiap titik eksekusi, beberapa utas lainnya (atau beberapa di antaranya!) mungkin mengeksekusi hampir semua bagian lain dari kode dan mengubah data yang Anda operasikan tepat di bawah mata Anda. Secara teori, itu dapat dikelola dengan mutex / monitor / bagian kritis / apa pun yang Anda sebut itu, tetapi dalam praktiknya tidak ada manusia biasa yang benar-benar dapat melakukan hal itu secara andal kecuali mereka secara drastis membatasi keadaan bersama dan / atau paralelisme menjadi sangat kecil. bagian dari kode.

Michael Borgwardt
sumber
9
Saya setuju dengan jawaban ini, tetapi bahkan dengan fungsi murni, pendekatan deklaratif (seperti CSS, atau XSLT, atau makeatau bahkan spesialisasi template C ++ dan kelebihan fungsi) dapat menempatkan Anda kembali pada posisi mempertimbangkan keseluruhan program. Bahkan sekali Anda merasa telah menemukan definisi sesuatu, bahasa tersebut memungkinkan deklarasi yang lebih spesifik di mana saja dalam program untuk menimpanya. IDE Anda mungkin bisa membantu.
Steve Jessop
4
Saya akan menambahkan bahwa dalam skenario multithreaded Anda juga harus memiliki pemahaman yang cukup mendalam tentang apa instruksi tingkat rendah yang diinginkan kode Anda: sebuah operasi yang terlihat sumber atom mungkin memiliki titik interupsi yang tidak terduga dalam eksekusi aktual.
Jared Smith
6
@SteveJessop: Memang, poin ini sering diabaikan. Ada alasan mengapa C # membuat Anda mengatakan ketika Anda ingin metode yang bisa ditimpa daripada diam-diam membuat overridability sebagai default; kami ingin mengibarkan bendera yang mengatakan "kebenaran program Anda mungkin bergantung pada kode yang tidak dapat Anda temukan pada waktu kompilasi" pada titik ini. (Yang mengatakan, saya juga berharap bahwa "disegel" adalah default untuk kelas di C #.)
Eric Lippert
@EricLippert Apa alasan terakhir untuk sealedtidak menjadi default?
Zev Spitz
@ZevSpitz: Keputusan itu dibuat jauh sebelum waktu saya; Saya tidak tahu
Eric Lippert
9

Dalam kasus pemrograman fungsional, makna "Mudah untuk alasan" adalah sebagian besar bersifat deterministik. Maksud saya, input yang diberikan akan selalu menghasilkan output yang sama. Anda dapat melakukan apa pun yang Anda inginkan pada program, selama Anda tidak menyentuh potongan kode itu, itu tidak akan rusak.

Di sisi lain, OO biasanya lebih sulit untuk dipikirkan karena "output" yang dihasilkan tergantung pada keadaan internal setiap objek yang terlibat. Cara khas yang dimanifestasikannya adalah efek samping yang tidak terduga : ketika mengubah satu bagian kode, bagian yang tampaknya tidak terkait akan terputus.

... Kelemahan pemrograman fungsional tentu saja dalam prakteknya, banyak yang ingin Anda lakukan adalah IO dan mengelola negara.

Namun, ada banyak hal lain yang lebih sulit untuk dipikirkan, dan saya setuju dengan @Kilian bahwa concurrency adalah contoh utama. Sistem terdistribusi juga.

dagnelies
sumber
5

Menghindari diskusi yang lebih luas, dan menjawab pertanyaan spesifik:

Bisakah Anda memberikan beberapa contoh "Bukan alasan yang mudah tentang", sehingga dapat dibandingkan dengan contoh "Alasan mudah tentang"?

Saya merujuk Anda ke "The Story of Mel, Programmer Nyata" , sepotong cerita rakyat programmer yang berasal dari tahun 1983 dan karena itu dianggap sebagai 'legenda', untuk profesi kami.

Ini menceritakan kisah seorang programmer menulis kode yang lebih suka teknik misterius sedapat mungkin, termasuk kode referensi diri dan modifikasi diri, dan eksploitasi bug mesin yang disengaja:

loop tak terhingga nyata sebenarnya telah dikodekan sedemikian rupa untuk mengambil keuntungan dari kesalahan carry-overflow. Menambahkan 1 ke instruksi yang diterjemahkan sebagai "Muat dari alamat x" biasanya menghasilkan "Muat dari alamat x + 1". Tetapi ketika x sudah menjadi alamat setinggi mungkin, alamat itu tidak hanya membungkus ke nol, tetapi 1 dibawa ke dalam bit dari mana opcode akan dibaca, mengubah opcode dari "load from" menjadi "jump to" jadi bahwa instruksi lengkap berubah dari "muat dari alamat terakhir" ke "lompat ke alamat nol".

Ini adalah contoh kode yang 'sulit untuk dipikirkan'.

Tentu saja, Mel tidak akan setuju ...

AakashM
sumber
1
+1 untuk merujuk pada kisah Mel, salah satu favorit abadi saya.
John Bollinger
3
Baca Kisah Mel di sini, karena artikel Wikipedia tidak memiliki tautan ke sana.
TRiG
@TRiG catatan kaki 3 di halaman, bukan?
AakashM
@ AashashM Entah bagaimana berhasil melewatkannya.
TRiG
5

Saya dapat memberikan contoh, dan yang sangat umum.

Pertimbangkan kode C # berikut.

// items is List<Item>
var names = new List<string>();
for (var i = 0; i < items.Count; i++)
{
    var item = items[i];
    var mangled = MyMangleFunction(item.Name);
    if (mangled.StartsWith("foo"))
    {
        names.Add(mangled);
    }
}

Sekarang pertimbangkan alternatif ini.

// items is List<Item>
var names = items
    .Select(item => MyMangleFunction(item.Name))
    .Where(s => s.StartsWith("foo"))
    .ToList();

Dalam contoh kedua, saya tahu persis apa yang dilakukan kode ini sekilas. Ketika saya melihat Select, saya tahu daftar item sedang dikonversi menjadi daftar yang lain. Ketika saya melihat Where, saya tahu bahwa beberapa item sedang disaring. Sekilas, saya bisa mengerti apa namesitu dan memanfaatkannya dengan efektif.

Ketika saya melihat sebuah forloop, saya tidak tahu apa yang terjadi sampai saya benar-benar membaca kode. Dan kadang-kadang saya harus melacaknya untuk memastikan saya telah memperhitungkan semua efek samping. Saya harus melakukan sedikit pekerjaan untuk memahami nama apa itu (di luar definisi tipe) dan bagaimana menggunakannya secara efektif. Jadi, contoh pertama lebih sulit untuk dipertimbangkan daripada yang kedua.

Pada akhirnya, menjadi mudah dipikirkan di sini juga tergantung pada pemahaman metode Selectdan LINQ Where. Jika Anda tidak mengenal mereka, maka kode kedua lebih sulit untuk dipikirkan pada awalnya. Tetapi Anda hanya membayar biaya untuk memahaminya sekali. Anda membayar biaya untuk memahami forloop setiap kali Anda menggunakan satu dan lagi setiap kali itu berubah. Kadang-kadang biayanya layak dibayar, tetapi biasanya "lebih mudah untuk alasan" jauh lebih penting.

Kasey Speakman
sumber
2

Ungkapan terkait adalah (I parafrase),

Itu tidak cukup untuk kode untuk memiliki " tidak ada bug yang jelas ": sebaliknya, itu harus memiliki " jelas tidak ada bug ".

Contoh yang relatif "mudah untuk dipikirkan" mungkin adalah RAII .

Contoh lain mungkin menghindari pelukan maut : jika Anda bisa memegang kunci dan mendapatkan kunci lain, dan ada banyak kunci, sulit untuk memastikan tidak ada skenario di mana pelukan maut mungkin terjadi. Menambahkan aturan seperti "hanya ada satu kunci (global)", atau, "Anda tidak diizinkan memperoleh kunci kedua saat Anda memegang kunci pertama", membuat sistem ini relatif mudah untuk dipikirkan.

ChrisW
sumber
1
Hmm. Saya tidak yakin RAII mudah dipikirkan. Tentu, mudah dipahami secara konseptual , tetapi semakin sulit untuk benar-benar beralasan tentang (yaitu, memprediksi) perilaku kode yang membuat penggunaan RAII ekstensif. Maksudku, itu pada dasarnya panggilan fungsi tidak terlihat di tingkat ruang lingkup. Fakta bahwa banyak orang mengalami kesulitan untuk berpikir tentang hal ini sangat jelas jika Anda pernah melakukan pemrograman COM .
Cody Grey
Maksud saya relatif mudah (C ++ dibandingkan dengan C): misalnya keberadaan konstruktor yang didukung bahasa berarti bahwa programmer tidak dapat membuat / memiliki / menggunakan objek yang mereka lupa untuk inisialisasi, dll.
ChrisW
Contoh berbasis COM itu bermasalah karena memadukan gaya, yaitu C ++ - style smart pointer ( CComPtr<>) dengan fungsi C-style ( CoUninitialize()). Saya menemukan itu contoh yang aneh, juga, sejauh saya ingat Anda memanggil CoInitialize / CoUninitialize pada lingkup modul dan untuk seluruh modul seumur hidup, misalnya dalam mainatau dalam DllMain, dan bukan dalam beberapa ruang lingkup fungsi lokal yang berumur pendek seperti ditunjukkan dalam contoh. .
ChrisW
Ini adalah contoh yang terlalu disederhanakan untuk tujuan ilustrasi. Anda sepenuhnya benar bahwa COM diinisialisasi pada lingkup modul, tetapi bayangkan contoh Raymond (seperti contoh Larry) sebagai fungsi titik masuk ( main) untuk aplikasi. Anda menginisialisasi COM saat startup, dan kemudian Anda unisialisasi itu tepat sebelum keluar. Kecuali Anda memiliki objek global, seperti COM smart pointer, menggunakan paradigma RAII. Mengenai gaya pencampuran: objek global yang menginisialisasi COM dalam ctornya dan tidak diinisialisasi dalam dtornya bisa diterapkan, dan apa yang disarankan Raymond, tetapi halus dan tidak mudah untuk dipikirkan.
Cody Grey
Saya berpendapat bahwa, dalam banyak hal, pemrograman COM lebih mudah untuk alasan di C, karena semuanya adalah panggilan fungsi eksplisit. Tidak ada yang tersembunyi atau tidak terlihat terjadi di belakang Anda. Ini sedikit lebih banyak pekerjaan (yaitu, lebih membosankan), karena Anda harus secara manual menulis semua panggilan fungsi itu dan kembali dan memeriksa pekerjaan Anda untuk melihat bahwa Anda telah melakukannya dengan benar, tetapi semuanya terbuka, yang merupakan kuncinya untuk membuatnya mudah untuk dipikirkan . Dengan kata lain, "terkadang pointer pintar terlalu pintar" .
Cody Grey
2

Inti dari pemrograman adalah analisis kasus. Alan Perlis mengomentari hal ini dalam Epigram # 32: Programmer tidak diukur dengan kecerdikan dan logika mereka tetapi dengan kelengkapan analisis kasus mereka.

Situasi mudah dipikirkan jika analisis kasusnya mudah. Ini berarti bahwa ada beberapa kasus untuk dipertimbangkan, atau, gagal, beberapa kasus khusus - mungkin ada beberapa ruang kasus yang besar, tetapi yang runtuh karena beberapa keteraturan, atau menyerah pada teknik penalaran seperti induksi.

Versi rekursif dari suatu algoritma, misalnya, biasanya lebih mudah untuk dipikirkan daripada versi imperatif, karena itu tidak berkontribusi pada kasus yang berlebihan yang muncul melalui mutasi variabel keadaan pendukung yang tidak muncul dalam verison rekursif. Selain itu, struktur rekursi sedemikian rupa sehingga cocok dengan pola pembuktian-per-induksi matematis. Kita tidak harus mempertimbangkan kompleksitas seperti varian loop dan prasyarat ketat terlemah dan yang lainnya.

Aspek lain dari ini adalah struktur ruang kasing. Lebih mudah untuk memikirkan tentang situasi yang memiliki pembagian flat, atau sebagian besar datar ke dalam kasus dibandingkan dengan situasi kasus hirarkis: kasus dengan sub-kasus dan sub-kasus dan sebagainya.

Properti sistem yang menyederhanakan penalaran adalah ortogonalitas : ini adalah properti bahwa kasus yang mengatur subsistem tetap independen ketika subsistem tersebut digabungkan. Tidak ada kombinasi yang menimbulkan "kasus khusus". Jika sesuatu empat kasus digabungkan dengan sesuatu tiga kasus secara ortogonal, ada dua belas kasus, tetapi idealnyasetiap kasus merupakan kombinasi dari dua kasus yang tetap independen. Dalam beberapa hal, sebenarnya tidak ada dua belas kasus; kombinasinya hanyalah "fenomena seperti kasus yang muncul" yang tidak perlu kita khawatirkan. Artinya, kita masih memiliki empat kasus yang dapat kita pikirkan tanpa mempertimbangkan tiga kasus lain di subsistem lainnya, dan sebaliknya. Jika beberapa kombinasi harus diidentifikasi secara khusus dan diberkahi dengan logika tambahan, maka alasannya lebih sulit. Dalam kasus terburuk, setiap kombinasi memiliki penanganan khusus, dan kemudian benar-benar ada dua belas kasus baru, yang merupakan tambahan dari empat dan tiga yang asli.

Kaz
sumber
0

Tentu. Ambil konkurensi:

Bagian kritis ditegakkan oleh mutex: mudah dimengerti karena hanya ada satu prinsip (dua utas eksekusi tidak bisa masuk ke bagian kritis secara bersamaan), tetapi rentan terhadap inefisiensi dan kebuntuan.

Model-model alternatif, misalnya pemrograman atau aktor bebas-kunci: berpotensi jauh lebih elegan dan kuat, tetapi sangat sulit untuk dipahami, karena Anda tidak dapat lagi bergantung pada (tampaknya) konsep dasar seperti "sekarang tulis nilai ini ke tempat itu".

Mudah dipikirkan adalah salah satu aspek dari suatu metode. Tetapi memilih metode mana yang akan digunakan membutuhkan mempertimbangkan semua aspek dalam kombinasi.

Kilian Foth
sumber
13
-1: contoh benar-benar buruk yang membuat saya berpikir Anda tidak mengerti apa arti kalimat itu sendiri. "Bagian kritis yang diberlakukan oleh mutex" sebenarnya adalah salah satu hal tersulit untuk dipikirkan di luar sana - hampir semua orang yang menggunakannya memperkenalkan kondisi ras atau kebuntuan. Saya akan memberikan Anda pemrograman bebas-kunci, tetapi inti dari model aktor adalah bahwa itu jauh, lebih mudah untuk dipikirkan.
Michael Borgwardt
1
Masalahnya adalah bahwa konkurensi itu sendiri merupakan topik yang sangat sulit untuk dipikirkan oleh para programmer, sehingga tidak memberikan contoh yang sangat bagus. Anda sepenuhnya benar bahwa bagian-bagian penting yang ditegakkan oleh mutex adalah cara yang relatif sederhana untuk mengimplementasikan konkurensi, dibandingkan dengan pemrograman bebas-penguncian, tetapi sebagian besar programmer seperti Michael, dan mata mereka berkaca-kaca ketika Anda mulai berbicara tentang bagian-bagian penting dan mutex, jadi ini tentu bukan hal yang mudah dimengerti. Belum lagi semua bug.
Cody Grey
0

Mari kita batasi tugas untuk alasan formal. Karena alasan humor atau inventif atau puitis memiliki hukum yang berbeda.

Meski begitu, ekspresinya didefinisikan secara samar-samar, dan tidak dapat diatur secara ketat. Tapi bukan berarti itu harus tetap redup bagi kita. Mari kita bayangkan bahwa suatu struktur sedang melewati beberapa pengujian dan mendapatkan nilai untuk titik yang berbeda. Tanda yang bagus untuk setiap poin berarti bahwa strukturnya nyaman di setiap aspek dan karenanya, "Mudah untuk dijelaskan".

Struktur "Mudah dipikirkan" harus mendapatkan nilai bagus untuk yang berikut:

  • Istilah dalam memiliki nama yang masuk akal, mudah dibedakan dan didefinisikan. Jika elemen memiliki beberapa hierarki, perbedaan antara nama orang tua dan anak harus berbeda dari perbedaan antara nama saudara kandung.
  • Jumlah jenis elemen struktural rendah
  • Jenis elemen struktural yang digunakan adalah hal-hal mudah yang kita terbiasa.
  • Elemen yang sulit dimengerti (rekursi, langkah meta, geometri 4+ dimensi ...) diisolasi - tidak secara langsung dikombinasikan satu sama lain. (misalnya, jika Anda akan mencoba memikirkan beberapa aturan rekursional yang berubah menjadi 1,2,3,4..n..dimensi dimensi, itu akan sangat rumit. Tetapi jika Anda akan mentransfer setiap aturan ini ke beberapa rumus tergantung pada n, Anda akan memiliki formula terpisah untuk setiap n-kubus dan secara terpisah aturan rekursi untuk formula tersebut. Dan bahwa dua struktur secara terpisah dapat dengan mudah dipikirkan)
  • Jenis elemen struktural jelas berbeda (misalnya, tidak menggunakan array campuran mulai dari 0 dan dari 1)

Apakah tes ini subyektif? Ya tentu saja. Tetapi ungkapan itu sendiri juga subjektif. Apa yang mudah bagi satu orang, tidak mudah bagi orang lain. Jadi, tes harus berbeda untuk domain yang berbeda.

Gangnus
sumber
0

Gagasan bahasa fungsional yang memungkinkan untuk dipikirkan berasal dari sejarah mereka, khususnya ML yang dikembangkan sebagai bahasa pemrograman yang analog dengan konstruksi yang digunakan oleh Logic for Computable Functions untuk penalaran. Sebagian besar bahasa fungsional lebih dekat dengan pemrograman formal calculii daripada imperatif, sehingga terjemahan dari kode ke input dari sistem sistem penalaran kurang memberatkan.

Sebagai contoh dari sistem penalaran, dalam pi-kalkulus, setiap lokasi memori yang dapat berubah dalam bahasa imperatif perlu direpresentasikan sebagai proses paralel yang terpisah, sedangkan urutan operasi fungsional adalah proses tunggal. Empat puluh tahun sejak dari LFC theorem prover, kami bekerja dengan GB RAM sehingga memiliki ratusan proses kurang menjadi masalah - Saya telah menggunakan pi-kalkulus untuk menghilangkan potensi deadlock dari beberapa ratus baris C ++, meskipun representasi memiliki ratusan Memproses pemikir menghabiskan ruang negara di sekitar 3GB dan menyembuhkan bug yang terputus-putus. Ini tidak mungkin terjadi di tahun 70-an atau membutuhkan superkomputer di awal 1990-an, sedangkan ruang keadaan dari program bahasa fungsional dengan ukuran yang sama cukup kecil untuk dipikirkan saat itu.

Dari jawaban yang lain, frasa tersebut menjadi frasa-gebrakan meskipun banyak kesulitan yang membuatnya sulit untuk beralasan tentang bahasa-bahasa imperatif yang terkikis oleh hukum Moore.

Pete Kirkham
sumber
-2

Mudah untuk diartikan adalah istilah yang spesifik secara budaya, itulah sebabnya sangat sulit untuk memberikan contoh konkret. Ini adalah istilah yang dilabuhkan kepada orang-orang yang melakukan penalaran.

"Mudah untuk alasan" sebenarnya adalah frase yang sangat deskriptif diri. Jika seseorang melihat kode, dan ingin menjelaskan apa yang dilakukannya, mudah =)

Oke, hancurkan. Jika Anda melihat kode, biasanya Anda ingin melakukan sesuatu. Anda ingin memastikan bahwa itu melakukan apa yang menurut Anda harus dilakukan. Jadi Anda mengembangkan teori tentang apa yang harus dilakukan kode, dan kemudian Anda beralasan untuk mencoba berdebat mengapa kode itu benar-benar berfungsi. Anda mencoba untuk berpikir tentang kode seperti manusia (bukan seperti komputer) dan mencoba merasionalisasi argumen tentang apa yang dapat dilakukan kode.

Kasus terburuk untuk "alasan mudah" adalah ketika satu-satunya cara untuk memahami apa yang dilakukan oleh kode adalah dengan masuk baris demi baris melalui kode seperti mesin Turing untuk semua input. Dalam hal ini, satu-satunya cara untuk alasan apapun tentang kode ini adalah untuk mengubah diri menjadi komputer dan jalankan di kepala Anda. Contoh-contoh kasus terburuk ini mudah dilihat dalam kontes pemrograman usang, seperti 3 baris PERL ini yang mendekripsi RSA:

#!/bin/perl -sp0777i<X+d*lMLa^*lN%0]dsXx++lMlN/dsM0<j]dsj
$/=unpack('H*',$_);$_=`echo 16dio\U$k"SK$/SM$n\EsN0p[lN*1
lK[d2%Sa2/d0$^Ixp"|dc`;s/\W//g;$_=pack('H*',/((..)*)$/)

Untuk alasan yang mudah, sekali lagi, istilah ini sangat kultural. Anda harus mempertimbangkan:

  • Keterampilan apa yang dimiliki nalar? Berapa banyak pengalaman?
  • Pertanyaan macam apa yang mungkin dimiliki si pemikir tentang kodenya?
  • seberapa yakin pemikir perlu?

Masing-masing mempengaruhi "mudah untuk alasan" berbeda. Ambil ketrampilan nalar sebagai contoh. Ketika saya mulai di perusahaan saya, disarankan agar saya mengembangkan skrip saya di MATLAB karena "mudah untuk dipikirkan." Mengapa? Nah, semua orang di perusahaan tahu MATLAB. Jika saya memilih bahasa yang berbeda, akan lebih sulit bagi siapa pun untuk mengerti saya. Nevermind bahwa keterbacaan MATLAB mengerikan untuk beberapa tugas, hanya karena itu tidak dirancang untuk mereka. Kemudian, ketika karier saya berkembang, Python menjadi semakin populer. Tiba-tiba kode MATLAB menjadi "sulit untuk dipikirkan" dan Python adalah bahasa preferensi untuk menulis kode yang mudah dipikirkan.

Pertimbangkan juga apa yang mungkin dimiliki pembaca. Jika Anda dapat mengandalkan pembaca Anda untuk mengenali FFT dalam sintaksis tertentu, itu "lebih mudah untuk alasan tentang" kode jika Anda tetap pada sintaks itu. Ini memungkinkan mereka melihat file teks sebagai kanvas yang Anda lukis FFT ke, daripada harus masuk ke detail seluk beluk. Jika Anda menggunakan C ++, cari tahu seberapa nyaman pembaca Anda dengan stdperpustakaan. Seberapa mereka suka pemrograman fungsional? Beberapa idiom yang keluar dari wadah perpustakaan sangat bergantung pada gaya idomatik yang Anda inginkan.

Penting juga untuk memahami jenis pertanyaan apa yang mungkin ingin dijawab oleh pembaca. Apakah pembaca Anda sebagian besar peduli dengan pemahaman dangkal terhadap kode, atau mereka mencari bug di dalam perut?

Betapa yakin pembaca harus benar-benar menarik. Dalam banyak kasus, alasan kabur sebenarnya cukup untuk mengeluarkan produk. Dalam kasus lain, seperti perangkat lunak penerbangan FAA, pembaca akan ingin memiliki alasan kuat. Saya menemukan sebuah kasus di mana saya berpendapat untuk menggunakan RAII untuk tugas tertentu, karena "Anda bisa mengaturnya dan melupakannya ... itu akan melakukan hal yang benar." Saya diberitahu bahwa saya salah tentang itu. Mereka yang akan membahas kode ini bukan tipe orang yang "hanya ingin melupakan detailnya." Bagi mereka, RAII lebih seperti tongkat gantung, memaksa mereka untuk memikirkan semua hal yang bisa terjadi ketika Anda meninggalkan ruang lingkup.

Cort Ammon
sumber
12
Kode Perl sulit dibaca ; bukan alasan . Jika saya memiliki kepentingan untuk memahaminya, saya akan menghapus kode. Kode yang sebenarnya sulit untuk dipikirkan adalah yang masih sulit dipikirkan ketika diformat dengan baik dengan pengidentifikasi yang jelas untuk semuanya, dan tidak ada trik kode golf.
Kaz