Apa contoh ketidakkonsistenan dan ketidaklengkapan di Unix / C?

20

Dalam esai terkenal Richard Gabriel The Rise of Worse is Better , ia membandingkan versi karikatur dari MIT / Stanford (Lisp) dan filosofi desain New Jersey (C / Unix) di sepanjang sumbu kesederhanaan, kebenaran, konsistensi, dan kelengkapan. Dia memberikan contoh dari "masalah PC kalah" ( dibahas di tempat lain oleh Josh Haberman ) untuk berpendapat bahwa Unix mengutamakan kesederhanaan implementasi daripada kesederhanaan antarmuka.

Satu contoh lain yang saya temukan adalah pendekatan yang berbeda untuk angka. Lisp dapat mewakili angka besar yang sewenang-wenang (hingga ukuran memori), sementara C membatasi angka ke jumlah bit tetap (biasanya 32-64). Saya pikir ini menggambarkan sumbu kebenaran.

Apa saja contoh untuk konsistensi dan kelengkapan? Berikut ini semua deskripsi Gabriel (yang ia akui adalah karikatur):

Pendekatan MIT / Stanford

  • Kesederhanaan - desainnya harus sederhana, baik dalam implementasi maupun antarmuka. Lebih penting untuk antarmuka menjadi sederhana daripada implementasi.
  • Kebenaran - desain harus benar dalam semua aspek yang dapat diamati. Kekeliruan sama sekali tidak diizinkan.
  • Konsistensi - desain tidak boleh tidak konsisten. Sebuah desain dibiarkan menjadi sedikit kurang sederhana dan kurang lengkap untuk menghindari ketidakkonsistenan. Konsistensi sama pentingnya dengan kebenaran.
  • Kelengkapan - desain harus mencakup situasi penting sebanyak praktis. Semua kasus yang diharapkan secara wajar harus dicakup. Kesederhanaan tidak diperbolehkan untuk mengurangi kelengkapan secara berlebihan.

Pendekatan New Jersey

  • Kesederhanaan - desainnya harus sederhana, baik dalam implementasi maupun antarmuka. Lebih penting agar implementasinya lebih sederhana daripada antarmuka. Kesederhanaan adalah pertimbangan terpenting dalam suatu desain.
  • Kebenaran - desain harus benar dalam semua aspek yang dapat diamati. Sedikit lebih baik menjadi sederhana daripada benar.
  • Konsistensi - desain tidak boleh terlalu tidak konsisten. Konsistensi dapat dikorbankan untuk kesederhanaan dalam beberapa kasus, tetapi lebih baik untuk menjatuhkan bagian-bagian dari desain yang berurusan dengan keadaan yang kurang umum daripada memperkenalkan kompleksitas implementasi atau inkonsistensi.
  • Kelengkapan - desain harus mencakup situasi penting sebanyak praktis. Semua kasus yang diharapkan secara wajar harus dicakup. Kelengkapan dapat dikorbankan demi kualitas lainnya. Bahkan, kelengkapan harus dikorbankan kapan pun kesederhanaan implementasi terancam. Konsistensi dapat dikorbankan untuk mencapai kelengkapan jika kesederhanaan dipertahankan; terutama yang tidak berharga adalah konsistensi antarmuka.

Harap dicatat saya tidak bertanya apakah Gabriel benar (yang merupakan pertanyaan yang tidak sesuai untuk StackExchange) tetapi untuk contoh-contoh dari apa yang dia maksudkan.

Ellen Spertus
sumber
6
Jika Anda penasaran, ini bukan masalah pekerjaan rumah. Saya gurunya. :-) Setelah dipikir-pikir, mungkin itu menjadikannya pekerjaan rumah saya.
Ellen Spertus
4
Saya berjuang untuk melihat mengapa pertanyaan ini bukan pada Unix & Linux (atau mungkin Rekayasa Perangkat Lunak ?). Bisakah Anda menguraikan dengan cara apa Anda membutuhkan perspektif CS tentang masalah ini? Juga, mohon klarifikasi apakah Anda ingin contoh positif atau negatif.
Raphael
Bukankah pertanyaan itu lebih cocok di programer.stackexchange.com ?
Basile Starynkevitch
Saya memposting ini ke CS karena saya menganggap desain bahasa sebagai salah satu bidang ilmu komputer yang mendasar, mencakup kemampuan komputabilitas, kompleksitas, arsitektur, kegunaan, dll. Saya bisa mempostingnya ke Unix / Linux, walaupun saya mencari yang lebih luas melihat. Sedangkan untuk Programmer, orang hampir selalu memusuhi saya ketika saya memposting di sana, bahkan ketika saya pikir saya pada topik, jadi saya tinggal jauh dari sana.
Ellen Spertus

Jawaban:

15

Judul pertanyaan menunjukkan bahwa beberapa inkonsistensi antarmuka pengguna dasar mungkin menarik bagi Anda:

Perintah Unix tidak mengikuti sintaks tertentu untuk menentukan opsi dan flag. Sebagai contoh, sebagian besar perintah menggunakan huruf tunggal yang diawali oleh '-' sebagai flag:, cat -n some_filetetapi pengecualian seperti tar tf some_file.tardan dd in=some_file out=some_other_file count=2ada dalam perintah yang umum digunakan.

Unix dan turunan serta kerabatnya memiliki beberapa sintaks ekspresi reguler yang sedikit berbeda. Kerang menggunakan "*" di mana program lain (grep, egrep, vi) menggunakan '. *'. egrep memiliki '+' dan '|' sebagai operator, grep tidak.

Antarmuka sistem panggilan "semuanya adalah file" dapat dianggap tidak lengkap: baca / tulis / cari / tutup tidak cocok dengan setiap perangkat I / O. Pengecualian yang sangat dibutuhkan dikelompokkan ke dalam panggilan "ioctl", tetapi perangkat seperti kartu suara bahkan tidak cocok dengan sangat baik.

Bruce Ediger
sumber
Jawaban bagus. Ketika saya melihat judulnya, saya langsung berpikir "ioctl" (dan fcntl) tetapi sekarang saya tidak perlu mengetikkan jawaban.
Louis
1
pola glob bukan regexs
jk.
8

Konsistensi

Lisp memiliki sintaks yang sangat konsisten, semua ekstensi bahasa dapat disematkan secara alami melalui makro dan semacamnya. C, di sisi lain, memiliki sintaks kode yang agak, yang memungkinkan seseorang untuk mengambil beberapa "jalan pintas", sehingga dalam beberapa kasus kode C benar-benar terlihat lebih sederhana.

Kelengkapan

Di Lisp, jika Anda tidak memiliki fitur bahasa tertentu yang Anda butuhkan, Anda bisa menerapkannya sendiri dengan makro. C juga memiliki preprosesor, tetapi agak membingungkan.

Daniil
sumber
8

String C tidak dapat berisi karakter 0 dan fungsi pustaka tidak cocok untuk berurusan dengan data biner.

Nama file pada sistem Unix tidak dapat berisi karakter 0 atau karakter 47 (garis miring).

Dalam implementasi asli Unix, nama file dibatasi hingga 14 karakter. Versi selanjutnya hanya melonggarkan batasan ini; mereka tidak menghilangkannya.

Ditambahkan : Kondisi E2BIGkesalahan sistem, ketika seseorang mencoba execdengan daftar argumen yang memiliki terlalu banyak argumen, atau terlalu banyak memori, atau lingkungan yang terlalu besar.

Unix terkenal karena pembatasan sewenang-wenang semacam ini. Sampai munculnya Perl pada tahun 1987, menangani set data besar, atau set data dengan catatan panjang, atau data biner, sangat tidak dapat diandalkan.

Mark Dominus
sumber
Tidak mengizinkan /tidak sewenang-wenang, perlu (?) Untuk menyelesaikan ambiguitas seperti /pemisah jalur. Saya baru saja membuat file 000, rupanya batasan spesifik hilang pada zaman GNU / Linux modern.
Raphael
Saya tidak bermaksud mengatakan bahwa larangan /itu sewenang-wenang, hanya saja panjang garis dan batas ukuran file sewenang-wenang. Intinya, bagaimanapun, desain yang berbeda dapat memungkinkan nama file mengandung garis miring, tetapi desainer Unix tidak anggap itu penting.
Mark Dominus
Saya yakin bahwa pada saat itu, batasan-batasan itu diperkenalkan karena pertimbangan kinerja; teknik yang tidak berkembang juga bisa berperan. Dari sudut pandang hari ini, mereka tampaknya dipertanyakan, itu sudah pasti. Mengenai /, saya ingin tahu: dengan asumsi jalan harus dikodekan sebagai string, bagaimana Anda melakukannya tanpa karakter khusus untuk pemisahan jalan?
Raphael
Saya tidak mengerti apa maksud Anda. Pertanyaannya menanyakan "contoh ketidakkonsistenan dan ketidaklengkapan di Unix / C"; itu tidak menyebutkan kinerja.
Mark Dominus
1
@ Raphael: Anda menyingkirkan masalah pemisah konyol dengan mendefinisikan pathtipe data abstrak, dan menggunakannya di antarmuka Anda alih-alih mengekspos implementasi tertentu (string ascii yang diakhiri null).
Pengembaraan Logika
4

IIRC guru saya mengatakan ketidakmampuan untuk menggunakan char *variabel dalam switchpernyataan dalam C adalah masalah ketidakkonsistenan, tetapi bagi saya itu adalah masalah umum (kelengkapan). Saya pikir lebih baik untuk menggunakan "konsistensi" hanya di Anda algoritma atau desain perangkat lunak tidak dalam pemrograman bahasa itu sendiri (setidaknya tidak dalam bahasa seperti C. mungkin bahasa kereta memiliki masalah konsistensi), karena bahasa pemrograman memiliki standar yang solid yang mendefinisikan domain aturan dan bekerja dengan menerapkan input ke aturan. Jadi, jika ada sesuatu yang tidak diizinkan dalam bahasa, itu direncanakan untuk tidak diizinkan dan tidak inkonsistensi dalam bahasa, IMHO.


  1. Saya telah menggunakan generalitas sebagai kelengkapan. Saya pikir mereka adalah hal yang sama. mungkin aku salah.
  2. Ini bukan jawaban. mungkin saran atau pendapat saya.
kecanduan
sumber
3

Contoh terbaik yang saya miliki adalah pengguna miskin yang memiliki nama file .. -rdan mengetik rm *.

Apakah cerita ini benar atau tidak, itu menjadi klasik pembenci Unix.

Lihat The Unix-Haters Handbook , yang memiliki pengantar oleh Dennis Ritchie sendiri, untuk banyak contoh ini.

Saya akan menambahkan lebih jauh bahwa menghindari jenis masalah ini adalah kekuatan utama dalam desain Microsoft Power Shell.

S. Robert James
sumber
Saya membaca esai Richard Gabriel di bagian belakang The Unix-Haters Handbook. :-)
Ellen Spertus
3
  • Tentu saja arti yang sangat banyak dari flag yang sama (pendek) untuk perintah adalah inkonsistensi.
  • Setiap program yang menggunakan ekspresi reguler memiliki sintaks sendiri untuk mereka
  • File konfigurasi untuk layanan semuanya adalah sintaks yang berbeda (yang dapat dimaafkan sebagian, daemon mailer Anda memiliki sedikit kesamaan dengan server web atau startup sistem Anda, tetapi masih)
  • Ada beberapa editor! Pengguna menggunakan kerang berbeda !! Mengapa ada begitu banyak lingkungan desktop?!?

OTOH, fakta bahwa shell memperluas gumpalan, dan bukan progam, menghilangkan banyak inkonsistensi menjengkelkan hadir dalam sistem lain. Ditto kenyataan bahwa Anda dapat menggunakan perintah yang sama untuk menyalin file dari satu tempat ke tempat lain di filessytem, ​​ke disket atau dari disk Zip ke tape.

Jadi, ya, Unix tidak konsisten. Begitu juga sistem lain, hanya berbeda ;-)

vonbrand
sumber
2

LISP yang mendukung angka presisi tak terbatas versus C yang hanya mendukung bilangan bulat mesin bukan merupakan contoh 'kebenaran' bahasa. Ini adalah masalah sederhana yang timbul dari fakta bahwa bahasa memiliki tujuan desain yang sangat berbeda.

Maksud C adalah menjadi bahasa yang dekat dengan mesin yang dapat digunakan untuk mengimplementasikan sistem operasi. Mesin (kebanyakan) tidak mendukung angka desimal dengan ketepatan tak terbatas. Mesin (kebanyakan) memang memiliki bilangan bulat dengan panjang bit tetap.

dave
sumber