KISS ("tetap sederhana, bodoh" atau "tetap sederhana bodoh", lihat misalnya di sini ) adalah prinsip penting dalam pengembangan perangkat lunak, meskipun tampaknya berasal dari rekayasa. Mengutip dari artikel wikipedia:
Prinsipnya dicontohkan dengan kisah Johnson menyerahkan tim insinyur desain beberapa alat, dengan tantangan bahwa pesawat jet yang mereka desain harus diperbaiki oleh mekanik rata-rata di lapangan dalam kondisi pertempuran hanya dengan alat-alat ini. Oleh karena itu, 'bodoh' mengacu pada hubungan antara cara memecahkan sesuatu dan kecanggihan yang tersedia untuk memperbaikinya.
Jika saya ingin menerapkan ini pada bidang pengembangan perangkat lunak, saya akan mengganti "pesawat jet" dengan "perangkat lunak", "mekanik rata-rata" dengan "pengembang rata-rata" dan "dalam kondisi tempur" dengan "di bawah pengembangan / pemeliharaan perangkat lunak yang diharapkan kondisi "(tenggat waktu, batasan waktu, pertemuan / gangguan, alat yang tersedia, dan sebagainya).
Jadi itu adalah ide yang umum diterima bahwa seseorang harus mencoba untuk membuat perangkat lunak tetap sederhana (atau bodoh sederhana , jika Anda menghilangkan koma) sehingga mudah untuk mengerjakannya nanti.
Tetapi dapatkah prinsip KISS diterapkan juga pada desain bahasa pemrograman? Apakah Anda tahu ada bahasa pemrograman yang telah dirancang khusus dengan prinsip ini dalam pikiran, yaitu untuk "memungkinkan programmer rata-rata di bawah kondisi kerja rata-rata untuk menulis dan mempertahankan kode sebanyak mungkin dengan upaya kognitif yang paling sedikit"?
Jika Anda mengutip bahasa tertentu, alangkah baiknya jika Anda dapat menambahkan tautan ke beberapa dokumen yang maksudnya dinyatakan dengan jelas oleh perancang bahasa. Bagaimanapun, saya akan tertarik untuk belajar tentang niat (didokumentasikan) desainer 'daripada pendapat pribadi Anda tentang bahasa pemrograman tertentu.
Jawaban:
Ketika saya memikirkan minimialisme, saya memikirkan Lisp dan Go . Dengan Lisp, yang Anda miliki hanyalah fungsi dan daftar, yang sesederhana yang Anda dapat (well, ada sedikit lagi, tapi apa pun). Namun, saya pikir kasus Go lebih menarik.
Go dirancang untuk menjadi sederhana (ini layak dibaca). Istilah yang mereka gunakan adalah "fitur orthogonality", yang berarti bahwa setiap fitur hanya boleh ditambahkan jika ia menyediakan sesuatu yang benar-benar unik. Ini tampaknya berasal dari para penulis ( keterlibatan Russ Cox dan Rob Pike datang ke pikiran) dengan Plan9 , yang merupakan reimaginasi dari UNIX dengan kesederhanaan dalam pikiran. (Jika Anda tertarik dengan desain minimal, makalah Rob Pike tentang sistem windowing sederhana adalah bacaan yang bagus.)
Berikut ini beberapa contoh sederhana sintaks:
Hanya satu konstruksi perulangan
Sebuah loop dapat terlihat seperti berikut ini:
Loop tak terbatas
Sementara loop
Tradisional untuk loop
Loop depan
Sakelar multiguna
Pengembalian ganda
Antarmuka
Menanamkan
Saluran
Dapat digunakan untuk mengimplementasikan semaphores
Digunakan untuk menyampaikan pesan di antara utas
Dapat digunakan untuk menangani acara asinkron
Kesimpulan
Saya tidak akan masuk ke setiap bagian dari sintaks, tetapi mudah-mudahan Anda bisa melihat apa yang bisa dilakukan minimalis. Bahasa ini menarik bukan karena menambahkan banyak fitur baru, tetapi karena menggunakan fitur terbaik dari bahasa lain tanpa tambahan apa pun.
Biasanya ada satu cara "terbaik" untuk memecahkan masalah. Misalnya, di milis, banyak pengguna mengeluh tidak memiliki obat generik. Setelah diskusi, mereka menyadari bahwa semua yang mereka ingin lakukan dapat dilakukan dengan antarmuka. Baca dengan efektif untuk contoh tentang sintaksis idiomatik.
Manfaat dari bahasa KISS adalah mungkin untuk menulis kode idiomatik, karena gaya kode dibatasi oleh bahasa tersebut. Misalnya, di Go, Anda tidak dapat menulis sesuatu seperti ini:
Anda harus menggunakan kurung kurawal:
Ada banyak contoh lain dari ini dalam sintaks, yang membuat membaca kode orang lain lebih mudah.
Manfaat bahasa KISS daripada bahasa fitur:
sumber
for i=1 to 10
for item in group
for i = 1 to 10
adalah apakahi
akan pernah 10. Ini bisa bergantung pada bahasa (bash termasuk 10, python tidak). Tradisional untuk loop adalah universal.Saya pikir Zen Python akan menyatakan mengapa Python adalah bahasa sederhana yang jauh lebih baik daripada yang saya bisa:
Edit dalam menanggapi @Giorgio
Seperti yang dinyatakan oleh pertanyaan Anda,
Bagi saya, Python adalah apa yang langsung terlintas dalam pikiran. Desain Python adalah respons langsung terhadap metodologi Perl, yang terkenal "Ada Lebih Dari Satu Cara Untuk Melakukannya". Meskipun bagus, memungkinkan programmer untuk dengan mudah menulis kode, itu tidak membantu dalam pemeliharaan. Setelah sebelumnya mengelola (sangat buruk ditulis, saya akui) program yang ditulis dalam Perl, saya menghargai Python memaksa kedua praktik pengkodean yang baik dan bahasa ringkas di tenggorokan Anda.
Python juga tidak memaksa Anda untuk mengikuti satu metodologi tertentu saat menulis program. Saya dapat memilih untuk mengikuti gaya pemrograman berorientasi objek yang ketat, atau saya dapat menulis skrip sederhana untuk dieksekusi secara berurutan. Tidak harus menginisialisasi kelas, maka panggil
main()
metode seperti yang Anda lakukan di Jawa sangat bagus. (Juga, mencetak ke stdout dengan Python sangat bagus, tapi itu poin yang agak nol).Akhirnya, metodologi "Termasuk Baterai" untuk menyertakan perpustakaan standar yang luas dengan bahasanya sangat bagus. Alih-alih berburu melalui beberapa repositori eksternal untuk paket, sebagian besar yang saya butuhkan sudah termasuk dalam bahasa. Ini juga menyenangkan memiliki repo eksternal, tetapi tidak harus menggali melalui itu untuk melakukan operasi dasar sangat berguna.
sumber
import this
perintah.Kunci utama untuk mempertahankan "kesederhanaan" adalah mengenali kapan kerumitan akan diperlukan, dan memiliki bagian-bagian dari sistem yang dapat mengatasinya, lakukanlah. Memiliki satu jenis referensi objek yang tidak membuat perbedaan antara nilai-nilai yang tidak berubah, nilai-nilai yang bisa berubah, dan entitas, membuat Java "sederhana", tidak menghilangkan kebutuhan untuk membedakan antara nilai dan entitas; itu hanya merampas alat programmer untuk membantu mereka melakukannya.
Lebih umum, jika seseorang mencoba untuk memiliki bahasa pemrograman atau fitur kerangka kerja mendukung banyak kasus penggunaan, seseorang harus memastikan bahwa tidak akan ada situasi di mana perilaku yang berbeda akan sesuai dalam kasus penggunaan yang berbeda, tetapi kompiler tidak akan dapat memberi tahu mereka terpisah. Menambahkan lebih banyak jenis ke bahasa atau kerangka kerja mungkin tampak seperti kerumitan, tetapi dalam banyak kasus hal itu justru membuat segalanya lebih mudah.
Pertimbangkan, misalnya, kekacauan aturan di sekitar tipe bertanda tangan dan tidak bertanda dalam C. Kompleksitas aturan ini berasal dari kenyataan bahwa beberapa kode menggunakan tipe integer tak bertanda untuk mewakili angka, sementara kode lain menggunakannya untuk mewakili anggota cincin aljabar yang membungkus (khusus, himpunan bilangan bulat mod 2 mod). Aturan konversi tipe berperilaku dengan cara yang kadang-kadang sesuai untuk satu penggunaan, dan kadang-kadang dengan cara yang sesuai untuk yang lain. Memiliki tipe pembungkus dan non-pembungkus yang terpisah akan menggandakan jumlah tipe integer, tetapi dapat menyederhanakan aturan yang terkait dengannya:
Jenis integer non-cincin dari ukuran apa pun dapat ditugaskan ke cincin dengan ukuran apa pun; sebuah cincin dapat ditugaskan hanya pada cincin dengan ukuran yang sama atau lebih kecil .
Operasi selain operator relasional yang melibatkan bilangan bulat non-cincin dan cincin secara implisit akan mengkonversi bilangan bulat ke jenis cincin.
Cincin dapat secara eksplisit dilemparkan ke angka atau ke cincin yang lebih besar; nilai cincin yang tidak ditandatangani adalah bilangan bulat non-negatif terkecil yang, ketika ditambahkan ke nol cincin, akan menghasilkan nilai cincin. Nilai cincin yang ditandatangani adalah bilangan bulat terkecil yang, ketika ditambahkan ke nol cincin, akan menghasilkan nilai cincin, dengan nilai negatif lebih disukai dalam kasus dasi.
Kecuali sebagaimana disebutkan di atas, cincin terbatas pada operasi dengan cincin dengan ukuran yang sama atau lebih kecil.
Operasi pada bilangan bulat non-ring dari tipe yang berbeda harus mengirimkan angka ke tipe yang dapat mengakomodasi semua nilai dari kedua operan, atau harus ditolak oleh kompiler jika tidak ada tipe yang sesuai.
Mendefinisikan tipe dering tampaknya akan menggandakan jumlah tipe integer, tetapi akan sangat menyederhanakan penulisan kode portabel. Menggunakan tipe unsigned yang sama untuk angka dan dering mengurangi jumlah jenis, tetapi mengarah pada aturan yang rumit yang membuatnya hampir mustahil untuk menulis kode portabel yang efisien.
sumber
Boleh dibilang, Tcl dikembangkan sepanjang jalur ini. Seluruh bahasa hanya dapat dijelaskan dalam 12 aturan pada satu halaman manual . Ini sangat sederhana dan konsisten.
Pencipta Tcl mengklaim yang berikut sebagai tujuan asli:
Dari " History of Tcl " - http://www.tcl.tk/about/history.html
sumber
Jika suatu bahasa diperbaiki dalam desainnya karena KISS, itu tidak dapat tumbuh. Bahasa yang tidak bisa tumbuh akan mati.
Dalam video berikut, Guy Steele dengan cerdik menjelaskan bahwa bahasa pemrograman harus dibiarkan tumbuh dan mengapa. Jika Anda menerapkan KISS, lalu bagaimana bahasa dapat tumbuh karena begitu dirilis, seperangkat alat itu diperbaiki dan tidak pernah diizinkan untuk berubah.
Ini adalah video berdurasi satu jam tetapi layak tonton. Jika Anda tidak tahu siapa Guy Steele sebenarnya Anda harus ketika berbicara tentang desain bahasa.
Saya memilih video ini sebagai jawabannya karena saya percaya bahwa menerapkan KISS pada desain bahasa secara umum adalah salah, dan berharap bahwa melihat pidato dari orang yang memiliki desain bahasa akan membantu memperluas pemahaman Anda tentang masa depan desain bahasa.
Karena Anda datang ke sini untuk belajar tentang desain bahasa dan saya memberi Anda alasan untuk tidak menggunakan KISS, itu adil bahwa saya menunjukkan sesuatu yang saya temukan bantuan dalam desain bahasa. Dimensi kognitif notasi
EDIT
Ketika saya menulis jawaban di atas, hal itu didasarkan pada alasan: jika sebuah mesin hanya dapat dirawat dengan seperangkat alat yang tetap maka rumusan ulang saya tentang makna sehubungan dengan desain bahasa adalah bahwa suatu bahasa tidak dapat berubah setelah dirilis. Komentar tersebut mengindikasikan bahwa bukan itu yang dimaksud. Jadi izinkan saya mengajukan jawaban yang dimodifikasi ini yang akan lebih sesuai dengan pemahaman yang direvisi.
Jika kita memperhatikan dimensi Kognitif notasi maka kita belajar bahwa ada banyak dimensi bersaing yang terkait dengan desain bahasa daripada hanya kesederhanaan dan jika Anda terlalu fokus pada satu notasi , Anda akan menderita pada yang lain. Dengan pertanyaan berfokus pada kesederhanaan (KISS) yang baik, dan didukung oleh orang-orang terkemuka dalam desain bahasa, saya menyampaikan pidato oleh Guy Steele untuk menunjukkan bahwa mencoba mempertahankan desain semata-mata sederhana akan berdampak pada dimensi lain. Lebih penting lagi saya mencoba menyampaikan bahwa Anda perlu melihat banyak dimensi dan menimbang pro dan kontra dari mereka, bukan hanya kesederhanaan.
sumber
Berikut ini kutipan besar dari Hardcore Visual Basic karya Bruce McKinney , yang pada gilirannya menempatkan kata-kata ke mulut para desainer BASIC, Kemeny dan Kurtz . Tekankan milikku.
sumber
Ini adalah hal yang baik Anda mengklarifikasi apa yang Anda maksud dengan "sederhana", karena dalam pikiran saya bahasa pemrograman sederhana adalah bahasa dengan sintaks minimal dan beberapa fitur (Skema, Forth, ML), yang tidak secara langsung menerjemahkan definisi Anda. Saya pikir Anda benar-benar mencari desain bahasa dengan RAD (pengembangan aplikasi cepat) dalam pikiran, dan ada beberapa dari mereka. Lihat utas StackOverflow ini, misalnya: /programming/66227/what-is-the-best-multi-platform-rad-language
sumber
Saya terkejut bahwa belum ada yang menyebutkan C, meskipun menempatkan kesederhanaan sebagai yang pertama dalam beberapa hal penting, seringkali sedemikian radikal sehingga programmer gagal untuk menghargai kesederhanaan:
Tidak ada sihir tersembunyi. Jika Anda menulis
a + b
dalam C, Anda memiliki jaminan bahwa itu akan dikompilasi ke instruksi assembler tunggal paling banyak.Bahkan dalam bahasa yang relatif sederhana seperti Java, pernyataan sederhana seperti
a + b
mungkin membutuhkan beberapa mikrodetik (jika variabelnya berupa string). Bahasa lain menambahkan banyak, lebih banyak lagi dengan contoh ekstrim C ++ di manaa + b
mungkin kelebihan beban untuk membuat gajah merah muda muncul. Tidak demikian di C: Jika itu bukan pemanggilan fungsi, itu tidak akan membutuhkan lebih dari beberapa nanodetik. Prediktabilitas kinerja ini adalah salah satu fitur kunci dari C, dan itu tentu saja merupakan bentuk kesederhanaan.Tipe data sesederhana mungkin sambil tetap menggambarkan semua struktur data menarik yang mungkin ingin Anda buat dalam memori: Hanya ada tipe dasar yang dapat ditangani CPU + agregasi (
struct
) + pengulangan (array) + referensi (petunjuk) ).Memang benar bahwa berbagai bahasa berbasis lisp jauh lebih sederhana daripada C dalam hal ini. Namun, mereka tidak mencoba untuk memungkinkan programmer untuk secara bebas memanipulasi memori seperti halnya C.
Orthogonality of features: Anda dapat dengan bebas menggabungkan fitur dan mereka akan bekerja bersama seperti yang diharapkan. Banyak bahasa gagal dengan membiarkan konstruksi tertentu hanya muncul dalam konteks yang ditentukan.
Ambil contoh array panjang variabel dalam C dan C ++: C memungkinkan panjang runtime di mana-mana sementara permintaan paling liberal untuk memperluas standar C ++ memungkinkan mereka hanya dalam konteks tertentu seperti array otomatis dan bahkan hanya ada di dimensi pertama. Ini memungkinkan C untuk menangani array multidimensi sejati dengan ukuran yang hanya diketahui saat runtime, sedangkan programmer C ++ dikurangi untuk menulis
data[k + (j + i*lineLength)*lineCount]
berulang-ulang.Contoh lain dari ini adalah pointer: Sebuah pointer data dalam C ini benar-benar tidak lebih dari hanya sebuah variabel yang menyimpan alamat memori dari beberapa variabel lainnya. Karena pointer itu sendiri adalah variabel, pointer ganda adalah hal yang terdefinisi dengan baik. Yaitu diberikan apa adanya
int
danint*
, jelas apa yangint**
harus. Bandingkan ini dengan referensi C ++ di mana Anda sama sekali tidak tahu apaint&&
yang diberi arti dariint
danint&
!)Memang benar bahwa kesederhanaan inilah yang telah menghasilkan C begitu banyak kebencian: Kesederhanaan bahasa memungkinkan para programmer lebih banyak kebebasan daripada yang baik bagi mereka, yang mengarah ke banyak masalah dengan perilaku yang tidak ditentukan dan petunjuk yang salah penanganan. Terutama kesederhanaan ortogonalitas yang memungkinkan seorang programmer untuk mendefinisikan suatu variabel sebagaimana
int (*array[m])(struct foo* (*arg)[n])
jenis yang cenderung membuat pembaca sakit kepala karena hal-hal yang sangat kompleks dapat diekspresikan dalam bentuk yang sangat ringkas dengan kombinasi liberal dari beberapa fitur sederhana . Ini adalah jenis kesederhanaan di mana C unggul, dan yang memberinya reputasi sebagai bahasa yang sulit digunakan.Selain itu, kesederhanaan bahasa memaksa programmer untuk menulis lebih banyak kode daripada lebih banyak bahasa yang kaya fitur, memberikan lebih banyak lahan subur bagi bug untuk berkembang. Namun demikian, itu tetap bahasa tingkat tinggi yang paling sederhana jika tujuan utama Anda adalah memprogram komputer nyata dan bukan mesin virtual.
sumber
Wikipedia bahasa Jawa - meskipun tidak secara eksplisit dinyatakan dalam Wikipedia, penyederhanaan disebutkan beberapa kali dan merupakan tujuan desain asli, karena satu-satunya bahasa yang mampu menggunakan OO (istilah yang digunakan secara longgar) pada masa itu adalah C ++, yang seperti kita ketahui, sangat kuat tetapi memiliki lebih dari beberapa perangkap untuk yang tidak waspada.
JVM dimaksudkan sebagai cara untuk menyederhanakan pengembangan lintas platform, dan "Tulis sekali Jalankan di mana saja" menjadi mantra Java selama beberapa tahun - sekali lagi, maksudnya adalah kerangka kerja itu sederhana untuk digunakan.
Saya percaya C # termasuk dalam kategori penyederhanaan bahasa.
sumber
Hm ... ini sebenarnya pertanyaan sulit untuk dijawab 'positif', karena ketika saya memikirkan kesederhanaan dalam desain bahasa pemrograman (dan apa yang 'lebih mudah' untuk dikerjakan), saya langsung memikirkan:
Ada sejumlah bahasa yang melakukan hal-hal ini dengan baik - tetapi yang muncul di kepala saya adalah bahasa yang tidak melakukan hal-hal dengan baik 'sebagai bahasa pemrograman': PHP.
[Penafian - Saya sudah menulis PHP dan PHP masih menjadi 'bahasa saya' untuk proyek web sederhana. Ini adalah kritik cinta ...]
Pertama, PHP berfungsi baik untuk lingkungan yang biasanya dijalankan di server-web. Mudah diatur, mudah dirawat, dll.
Di mana saya bergumul dengan PHP: ketika Anda ingin melakukan sesuatu yang "tidak biasa" - sesuatu yang biasanya tidak Anda lakukan secara teratur (dalam hal ini saya berpikir itu memakan layanan web SABUN - bukan sesuatu yang saya miliki dilakukan banyak dengan PHP), Anda dihadapkan dengan dua opsi:
1) Berbagai ekstensi open source ke PHP. Model objek PHP cukup longgar di mana desain antarmuka juga tidak terlalu konsisten dari perpustakaan ke perpustakaan, pengembang ke pengembang. Ketika dihadapkan dengan seperangkat kode di mana seseorang menggunakan perpustakaan yang belum pernah Anda dengar, Anda menghabiskan banyak waktu mencari tahu 'apa yang harus dilakukan' karena bahasa ini memungkinkan pembuatan API / perpustakaan yang longgar.
2) Fungsi "built-in" - yang ada banyak . Saya telah melalui beberapa lubang kelinci baik menemukan perpustakaan lain atau menerapkan sedikit fungsionalitas untuk entah bagaimana nanti tersandung
impossiblyfound_basefunction()
Menurut saya, kesederhanaan adalah konsistensi.
sumber
Sekarang, pendekatan KISS untuk bahasa pemrograman adalah gagasan yang lucu, setidaknya jika Anda menganggap bahasa pemrograman sebagai lapisan abstraksi ke set instruksi CPU, dll. Jika Anda tidak mendefinisikan "KISS" lebih dekat. Saya hanya mengatakan di sini, bahwa gerobak sapi KISS diterapkan ke mobil sepenuhnya.
Sekarang interpretasi lain dari KISS bisa berupa "dilakukan dengan cerdas tanpa ornamen yang tidak perlu dan tidak terlalu rumit". Terutama orang dapat berargumen, bahwa seharusnya tidak ada terlalu banyak kasus spesifik untuk hal-hal serupa, dll. Biasanya matematika cukup bagus untuk meringkas hal-hal pada esensinya, dan - o heran - matematikawan telah menghabiskan waktu untuk memikirkan pemrograman dan komputer juga .
Untuk pemrograman, ada 2 model abstrak yang cukup terkenal:
Hal yang menyenangkan adalah: Meskipun mesin turing cukup sederhana dalam tata letaknya, itu bukan sistem yang mudah ditangani dan saya tidak berpikir itu memenuhi syarat untuk "smart KISS". Tetapi Lambda Calculus lebih berkaitan dengan bahasa pemrograman yang kita tahu - dan dengan Lisp dan Skema fitur perintis dari kalkulus lambda telah membuat jalannya menjadi banyak bahasa.
Lisp dan Skema BENAR-BENAR sederhana, setidaknya sintaks bijaksana. Sintaks adalah masalah utama dengan bahasa pemrograman (yang mungkin mengapa mereka diciptakan kembali sepanjang waktu). Dalam kasus C ++ hampir tidak dapat ditangani oleh otak manusia untuk memprediksi bagaimana beberapa baris sumber ditafsirkan oleh kompiler.)
Lisps mengurangi kompleksitas sintaksis secara keseluruhan dengan memperkenalkan satu bentuk umum untuk perintah:
Ini bisa menjadi panggilan metode, seperti
serta cabang if, loop dll.
(semua kode di sini adalah pseudo-Lisp / Dialect agnostic)
Formulir
juga bisa diartikan sebagai daftar
Dan itu adalah dasar untuk kesederhanaan dan keindahan Lisps. Karena daftar bersarang (seperti dalam
if
contoh pernyataan) merupakan pohon dan itu dapat dengan mudah dipahami oleh mesin dan oleh manusia di depan mesin.Fitur lain dari Lisps adalah makro saya tidak akan masuk ke detail kotor di sini, tetapi karena tidak ada perbedaan sintaksis antara panggilan fungsi normal dan "Sintaks (telur untuk loop, deklarasi variabel, dll., Semua yang harus ditangani oleh parser di lain bahasa pemrograman) Anda dapat membuat sintaks Anda sendiri. Makro pada dasarnya adalah Manipulasi Pohon yang merupakan program Anda.
Saya pikir Lisp memiliki KISS untuk pemrograman. Bahwa Anda dapat memanipulasi sintaks dengan menggunakan macro telah mengarah pada fenomena yang Lisp telah berevolusi secara cukup dinamis. Perlu fitur Bahasa baru seperti - katakanlah orientasi objek - cukup tulis sistem OOP dengan makro!
Sementara C diperpanjang bundaran 2 kali dengan fitur OOP (C ++, Obj. C) Lisp diperpanjang beberapa kali, pada akhirnya ada pemenang.
Itu adalah kekhasan lain tentang Lisp, itu berevolusi (lihat Clojure dan Clojurescript untuk mutasi baru yang menarik dari lisp).
Untuk sifat KISS-nya Lisps lebih disukai sebagai pengajaran bahasa oleh beberapa orang. Seperti Fogus menguraikan dalam cetak biru bahasa pendidikan ( http://blog.fogus.me/2013/01/21/enfield-a-programming-language-designed-for-pedagogy/ )
sumber