Apa cacat desain terbesar yang Anda hadapi dalam bahasa pemrograman apa pun? [Tutup]

29

Semua bahasa pemrograman memiliki kekurangan desainnya hanya karena tidak ada satu bahasa pun yang sempurna, seperti halnya dengan sebagian besar (semua?) Hal lain. Selain itu, kesalahan desain mana dalam bahasa pemrograman yang paling membuat Anda jengkel sepanjang sejarah Anda sebagai seorang programmer?

Perhatikan bahwa jika suatu bahasa "buruk" hanya karena bahasa itu tidak dirancang untuk hal tertentu bukan cacat desain, tetapi fitur desain, jadi jangan daftar gangguan bahasa seperti itu. Jika suatu bahasa ditentukan untuk apa ia dirancang untuk, itu tentu saja merupakan cacat dalam desain. Implementasi hal-hal spesifik dan di bawah tenda hal-hal tidak masuk hitungan.

Anto
sumber
6
Perhatikan bahwa ini konstruktif untuk perancang bahasa (kesalahan yang harus dihindari), jika seseorang ingin mempertanyakan seberapa konstruktif pertanyaan ini.
Anto
1
@ Greyfade: Tidak juga, ini adalah tentang kekurangan dalam bahasa aktual, yang tampaknya tentang hal-hal yang adopsi bahasa yang lebih rendah, yang dapat mencakup perpustakaan standar yang buruk atau hanya situs web yang buruk untuk bahasa tersebut. Beberapa daftar jawaban mis. Sintaks yang buruk, tetapi itu bukan cacat desain yang spesifik
Anto
8
Kelemahan terbesar dalam bahasa pemrograman apa pun? Manusia.
Joel Etherton
Jika jawaban ini adalah kelemahan terbesar, maka saya benar-benar terkesan dengan bahasa pemrograman.
Tom Hawtin - tackline

Jawaban:

42

Salah satu gangguan besar saya adalah cara switchkasus dalam bahasa yang diturunkan dari C default untuk jatuh ke kasus berikutnya jika Anda lupa untuk menggunakan break. Saya mengerti bahwa ini berguna dalam kode level sangat rendah (mis. Perangkat Duff ), tetapi biasanya tidak sesuai untuk kode level aplikasi, dan merupakan sumber umum kesalahan pengkodean.

Saya ingat sekitar tahun 1995 ketika saya membaca tentang rincian Jawa untuk pertama kalinya, ketika saya sampai pada bagian tentang switchpernyataan itu, saya sangat kecewa karena mereka mempertahankan perilaku gagal bayar yang baku. Ini hanya membuat switchdimuliakan gotodengan nama lain.

Greg Hewgill
sumber
3
@Christopher Mahan: switchtidak harus bekerja seperti itu. Misalnya, ada kasus / ketika pernyataan (setara dengan beralih / kasus) tidak memiliki perilaku jatuh.
Greg Hewgill
2
@Reg: switch-seperti pernyataan dalam bahasa yang tidak terkait dengan C tidak harus bekerja seperti itu. Tetapi jika Anda menggunakan kontrol aliran C-gaya ( {... }, for (i = 0; i < N; ++i), return, dll), bahasa inferensi akan membuat orang berharap switchuntuk bekerja seperti C, dan memberikan Ada / Pascal / orang DASAR-seperti semantik akan bingung. C # membutuhkan breakdi switchpernyataan untuk alasan yang sama, meskipun merek kurang rawan kesalahan dengan melarang fallthrough diam. (Tapi saya harap Anda bisa menulis fall;alih-alih yang jelek goto case.)
dan04
4
maka jangan menulis switch, tulis if () else. alasan Anda mengeluh tentang apa yang membuat beralih lebih baik: itu bukan kondisi yang benar / salah, itu kondisi angka, dan itu membuatnya berbeda. Anda juga bisa menulis fungsi sakelar Anda sendiri.
jokoon
9
-1 Saya menganggapnya bermanfaat untuk membiarkan jatuh, tidak ada bahaya selain kebodohan, namun memberikan fungsi tambahan.
Orbling
11
Masalahnya bukan itu switch memungkinkan fallthrough. Sebagian besar penggunaan fallthrough tidak disengaja.
dan04
41

Saya tidak pernah benar-benar menyukai penggunaan =untuk penugasan dan ==untuk pengujian kesetaraan dalam bahasa yang diturunkan dari C. Potensi kebingungan dan kesalahan terlalu tinggi. Dan bahkan jangan mulai saya menggunakan ===Javascript.

Lebih baik :=untuk tugas dan =untuk pengujian kesetaraan. Semantik bisa persis sama dengan yang ada sekarang, di mana penugasan adalah ekspresi yang juga menghasilkan nilai.

Greg Hewgill
sumber
3
@Nemanja Trifunovic: Saya awalnya memikirkan saran itu, tetapi memiliki ambiguitas yang disayangkan di C dengan perbandingan yang kurang dibandingkan dengan angka negatif (mis. x<-5). Pemrogram C tidak akan mentoleransi ruang kosong seperti itu yang diperlukan :)
Greg Hewgill
7
@ Greg: Saya lebih suka :=dan ==karena itu akan terlalu mudah untuk melupakan :dan tidak diberitahu seperti itu sudah terjadi (meskipun dikembalikan) ketika Anda lupa =hari ini. Saya berterima kasih atas peringatan kompiler tentang ini ...
Matthieu M.
13
Pada hampir semua keyboard yang pernah saya gunakan, ": =" memerlukan perubahan tombol shift saat mengetiknya. Pada yang saya gunakan sekarang, ':' adalah huruf besar dan '=' adalah huruf kecil, dan saya sudah terbalik. Saya mengetik banyak tugas, dan tidak perlu kesulitan mengetik seperti itu.
David Thornley
14
@ David Thornley: Kode dibaca lebih banyak kali daripada yang tertulis. Saya tidak membeli argumen apa pun tentang "kerumitan mengetik".
Greg Hewgill
8
@Greg Hewgill: Tentu itu lebih sering dibaca daripada ditulis. Namun, masalah antara =dan ==tidak dalam membaca, karena mereka adalah simbol yang berbeda. Ada dalam bentuk tertulis dan memastikan Anda mendapatkan yang benar.
David Thornley
29

Pilihan +dalam Javascript untuk penambahan dan penggabungan string adalah kesalahan yang mengerikan. Karena nilai tidak diketik, ini mengarah ke aturan Bizantium yang menentukan apakah +akan menambah atau menyatukan, tergantung pada konten yang tepat dari setiap operan.

Akan mudah pada awalnya untuk memperkenalkan operator yang sama sekali baru seperti $untuk penggabungan string.

Greg Hewgill
sumber
13
@ Barry: Tidak juga. +membuat banyak akal sebagai operator rangkaian string dalam bahasa yang sangat diketik. Masalahnya adalah bahwa Javascript menggunakannya tetapi tidak diketik dengan kuat.
Mason Wheeler
13
@ Alasan: +tidak masuk akal untuk penggabungan, karena penggabungan pasti tidak komutatif. Ini merupakan penyalahgunaan sejauh yang saya ketahui.
Matthieu M.
12
@Matthieu: Umm ... mengapa itu penting? Penggabungan tidak komutatif (seperti penambahan), tetapi penambahan dua string tidak masuk akal sehingga tidak ada yang berpikir seperti itu. Anda menemukan masalah di mana tidak ada.
Mason Wheeler
4
cukup beralih ke C ++ dan tambahkan segala jenis kelebihan beban esoterik ke operator pilihan Anda
Newtopian
8
@Matthieu: Commutativity bukan masalah di sini. Jika JS memiliki kelas Matrix, apakah Anda akan menganggapnya sebagai penyalahgunaan untuk memiliki *operator?
dan04
24

Saya menemukan Javascript default untuk global ke masalah besar, dan sering sumber bug jika Anda tidak menggunakan JSLint atau sejenisnya

Zachary K
sumber
2
Default ke global? Saya senang saya tidak menggunakan JS kalau begitu ...
Anto
5
Sebenarnya itu adalah bahasa yang sangat bagus, dengan beberapa pilihan desain yang buruk di dalamnya. Ini adalah yang utama, jika Anda tidak membuat ruang lingkup variabel itu akan ruang lingkup itu sebagai global. Hal yang baik adalah bahwa dengan menggunakan program Jslint Doug Crockford Anda dapat menangkap kesalahan ini dan banyak lagi.
Zachary K
1
Cukup gunakan varsetiap kali Anda mendeklarasikan variabel dan Anda siap melakukannya. Dan jangan bilang terlalu banyak mengetik karena Java memaksa Anda untuk mendeklarasikan semua tipe dua kali dan tidak ada yang mengeluh bahwa itu adalah pilihan desain yang buruk.
davidk01
3
@ davidk01: Orang-orang mengeluhkan hal itu. Demikian pula, orang-orang mengeluh karena harus mendeklarasikan std::map<KEY, VALUE>::const_iteratorvariabel dalam C ++ cukup yang autoditambahkan ke bahasa itu.
dan04
1
yang "use strict"direktif, ditambahkan dalam ES5, perubahan referensi dideklarasikan dalam kesalahan.
Sean McMillan
22

Preprosesor dalam C dan C ++ adalah lumpur yang sangat besar, menciptakan abstraksi yang bocor seperti saringan, mendorong kode spageti melalui sarang #ifdefpernyataan tikus , dan membutuhkan ALL_CAPSnama-nama yang sangat sulit dibaca untuk mengatasi keterbatasannya. Akar dari masalah ini adalah bahwa ia beroperasi pada level tekstual daripada level sintaksis atau semantik. Seharusnya diganti dengan fitur bahasa nyata untuk berbagai kasus penggunaannya. Berikut adalah beberapa contoh, meskipun diakui beberapa di antaranya diselesaikan dalam C ++, C99 atau ekstensi standar tidak resmi tapi de facto :

  • #include seharusnya diganti dengan sistem modul nyata.

  • Fungsi dan template / generik sebaris dapat menggantikan sebagian besar kasus penggunaan panggilan fungsi.

  • Beberapa jenis fitur konstan manifes / kompilasi waktu dapat digunakan untuk mendeklarasikan konstanta tersebut. Ekstensi D enum sangat bagus di sini.

  • Makro sintaks tingkat pohon nyata dapat memecahkan banyak kasus penggunaan lain-lain.

  • String mixin dapat digunakan untuk kasus penggunaan kode injeksi

  • static ifatau versionpernyataan dapat digunakan untuk kompilasi bersyarat.

dsimcha
sumber
2
@dsimcha: Saya setuju dengan #includemasalah ini, tetapi sistem modul ditemukan ... sesudahnya! Dan C dan C ++ bertujuan untuk kompatibilitas maksimal: /
Matthieu M.
@ Matthieu: Ya, sistem modul diciptakan setelah kata-kata, tapi bagaimanapun juga kita berbicara tentang tinjauan balik.
dsimcha
3
Saya setuju bahwa ini adalah rasa sakit yang luar biasa di berbagai bagian tubuh, tetapi desain multi-pass memiliki keunggulan kesederhanaan: sebuah kompiler C tidak perlu tahu banyak tentang konteks operasi sebelum dapat berhasil menyusun potongan kode C . Ini hanya dapat dikualifikasikan sebagai kesalahan desain jika Anda dapat menunjukkan bahwa biaya menggunakan sistem modul hipotetis dalam bahasa C itu sendiri (misalnya kelas C ++ - seperti) selalu lebih rendah dari atau sebanding dengan #includeperetasan berbasis cpp saat ini .
reinierpost
Saya setuju. Namun, tetapi beberapa orang berpikir bahwa preprocessing adalah hal yang baik, dan mengeluh bahwa itu tidak didukung di (misalnya) Jawa.
Stephen C
5
@Stephen: Saya setuju bahwa Java dengan preprocessor mungkin lebih baik daripada Java tanpa, tetapi hanya karena Java tidak memiliki beberapa fitur "nyata" yang diperlukan untuk mengganti preprocessor. Dalam bahasa seperti D, yang mencakup fitur dan Python, yang mendapatkan fleksibilitas dengan cara lain dengan menjadi dinamis, saya tidak ketinggalan sedikit pun.
dsimcha
21

Orang bisa membuat daftar ratusan kesalahan dalam ratusan bahasa, tetapi IMO itu bukan latihan yang berguna dari perspektif desain bahasa.

Mengapa?

Karena sesuatu yang akan menjadi kesalahan dalam satu bahasa tidak akan menjadi kesalahan dalam bahasa lain. Contohnya:

  • Membuat bahasa C yang dikelola (yaitu sampah dikumpulkan) atau mengikat jenis primitif akan membatasi kegunaannya sebagai bahasa tingkat rendah semi-portabel.
  • Menambahkan manajemen memori gaya-C ke Java (misalnya, untuk mengatasi masalah kinerja) akan merusaknya.

Ada yang pelajaran yang bisa dipelajari, tetapi pelajaran jarang dipotong jelas, dan untuk memahami mereka Anda harus memahami teknis trade-off ... dan konteks historis. (Misalnya, implementasi generik Java yang rumit adalah konsekuensi dari persyaratan bisnis utama untuk mempertahankan kompatibilitas ke belakang.)

IMO, jika Anda serius mendesain bahasa baru, Anda harus benar-benar menggunakan berbagai bahasa yang ada (dan mempelajari bahasa historis) ... dan putuskan sendiri apa kesalahannya. Dan Anda harus ingat bahwa masing-masing bahasa ini dirancang dalam konteks historis tertentu, untuk memenuhi kebutuhan tertentu.

Jika ada pelajaran umum yang dapat dipetik, mereka berada di tingkat "meta":

  • Anda tidak dapat merancang bahasa pemrograman yang ideal untuk semua tujuan.
  • Anda tidak dapat menghindari membuat kesalahan ... terutama jika dilihat dari belakang.
  • Banyak kesalahan menyakitkan untuk dikoreksi ... bagi pengguna bahasa Anda.
  • Anda harus memperhitungkan latar belakang dan keterampilan audiens target Anda; yaitu programmer yang ada.
  • Anda tidak bisa menyenangkan semua orang.
Stephen C
sumber
9
-1 - bahasa pemrograman mengikuti tujuan desain. Ciri-ciri bahasa yang bertentangan dengan tujuan-tujuan ini adalah cacat desain, kecuali jika itu merupakan kompromi yang diperlukan untuk salah satu tujuan lainnya. Tidak banyak bahasa dibuat dengan tujuan memuaskan semua orang, tetapi semua bahasa harus berusaha memuaskan orang-orang yang ingin memuaskannya. Jenis kebenaran politis postmodernistik ini cukup mencekik penelitian dan pengembangan bahasa pemrograman.
Rei Miyasaka
Maksud saya adalah sulit untuk belajar pelajaran tanpa memperhitungkan tujuan desain.
Stephen C
1
Sepertinya saya bahwa OP sudah memperhitungkan jawaban Anda di paragraf kedua dari pertanyaan.
Aidan Cully
20

C dan C ++ : Semua tipe integer yang tidak berarti apa - apa.

Terutama char. Apakah itu teks atau bilangan bulat kecil? Jika teks, apakah itu karakter "ANSI" atau unit kode UTF-8? Jika bilangan bulat, apakah ditandatangani atau tidak ditandatangani?

int dimaksudkan untuk menjadi integer berukuran "asli", tetapi pada sistem 64-bit, tidak.

longmungkin atau mungkin tidak lebih besar dari int. Mungkin ukuran pointer atau tidak. Ini cukup banyak keputusan sewenang-wenang pada bagian penulis kompiler apakah itu 32-bit atau 64-bit.

Jelas merupakan bahasa tahun 1970-an. Sebelum Unicode. Sebelum komputer 64-bit.

dan04
sumber
10
C tidak dirancang untuk menjadi bahasa standar yang cocok untuk semua, oleh karena itu C tidak dapat menjadi kesalahan desain. Itu dirancang untuk memodelkan cpu sebagai assembler portabel menghindari kode assembler cpu-spesifik. Namun, itu diperbaiki di Jawa.
7
Saya pikir masalah yang lebih besar adalah bahasa yang lebih baru yang terus menggunakan istilah tanpa arti yang sama, meskipun sejarah menunjukkan kepada kita itu adalah ide yang mengerikan. Setidaknya orang-orang C melihat kesalahan mereka dan menciptakan tipe int standar.
Mark H
5
Char bukanlah unit utf-8. Karakter utf-8 membutuhkan waktu lebih dari 8 bit untuk disimpan. C bukan bahasa tahun 1970-an, saya menggunakannya untuk proyek sekarang (secara sukarela).
dan_waterworth
4
C sedikit lebih dari abstraksi tingkat tinggi dari prosesor PDP-11. Sebagai contoh, kenaikan pra dan pasca secara langsung didukung oleh PDP-11.
bit-twiddler
5
Ini adalah jawaban yang sangat salah arah. Pertama, C dan C ++ tidak dapat dipertukarkan. Kedua, spesifikasi bahasa dengan jelas mendefinisikan apa char - Objek yang dideklarasikan sebagai tipe char cukup besar untuk menyimpan anggota dari set karakter eksekusi dasar. . Ketiga, C bukan "bahasa 70-an", itu adalah bahasa yang hidup dekat dengan perangkat keras dan mungkin bahasa yang pada akhirnya memungkinkan semua abstraksi tingkat tinggi Anda benar-benar masuk akal ke CPU. Anda menjadi orang yang hanya tahu bahasa tingkat tinggi dan tidak menghargai bagaimana hal-hal sebenarnya bekerja. -1
Ed S.
18

null.

Penemunya, Tony Hoare, menyebutnya "kesalahan miliar dolar" .

Itu diperkenalkan di ALGOL di tahun 60-an, dan ada di sebagian besar bahasa pemrograman yang umum digunakan saat ini.

Alternatif yang lebih baik, yang digunakan dalam bahasa seperti OCaml dan Haskell, adalah mungkin . Gagasan umum adalah bahwa referensi objek tidak boleh nol / kosong / tidak ada kecuali ada indikasi eksplisit bahwa mereka mungkin begitu.

(Meskipun Tony luar biasa dalam kesederhanaannya, saya pikir hampir semua orang akan melakukan kesalahan yang sama, dan kebetulan dia yang pertama.)

Rei Miyasaka
sumber
Tidak setuju, bahkan dengan penemunya !!! null adalah nilai kosong untuk tipe data pointer / referensi. String memiliki string kosong, set memiliki set kosong (Pascal empty set = []), integer memiliki 0. Sebagian besar bahasa pemrograman yang menggunakan null / nil / apa pun, jika variabel ditugaskan dengan benar kesalahan nol dapat dicegah.
umlcat
4
@ user14579: Setiap bahasa yang mendukung segala jenis set atau string atau array memiliki {}, tetapi demikian masih semantik yang sesuai dan tidak akan crash kecuali Anda sudah memiliki sesuatu yang mungkin dapat menyebabkan kesalahan batas array - tapi itu masalah lain. Anda dapat memproses string kosong untuk huruf besar semua karakter, yang akan menghasilkan string kosong. Anda mencoba hal yang sama pada string nol, dan tanpa pertimbangan yang tepat, itu akan macet. Masalahnya adalah bahwa pertimbangan yang tepat ini membosankan, sering dilupakan, dan membuatnya sulit untuk menulis fungsi ekspresi tunggal (yaitu lambda).
Rei Miyasaka
1
Saya menghasilkan uang setiap kali saya mengetik nol ... oh benar seseorang kehilangan uang setiap kali saya mengetik nol. Kecuali saat ini.
kevpie
3
@umlcat - ketika Anda memiliki bahasa dengan pencocokan pola seperti Ocaml, Haskell, dan F #, menggunakan Maybe x | Tidak ada pola yang mencegah Anda melupakan kasus nol pada waktu kompilasi. Tidak ada jumlah tipu daya waktu kompilasi yang dapat menangkap kesalahan dalam bahasa di mana nol adalah idiom yang sudah ada. Karena Anda harus secara eksplisit memilih untuk tidak berurusan dengan kasus nol dalam bahasa yang memiliki monumen Maybe and Some, mereka memiliki keunggulan serius atas pendekatan "null".
JasonTrue
1
@Jason - Saya suka menganggapnya maybesebagai null opt-in, sedangkan pengecualian nol adalah opt-out. Tentu saja ada beberapa hal yang bisa dikatakan tentang perbedaan antara kesalahan runtime dan kesalahan waktu kompilasi juga, tetapi fakta bahwa null pada dasarnya menyuntikkan perilaku adalah hal yang patut diperhatikan.
Rei Miyasaka
14

Saya merasa bahwa orang-orang yang merancang PHP tidak menggunakan keyboard normal, mereka bahkan tidak menggunakan keyboard colemak, karena mereka seharusnya menyadari apa yang mereka lakukan.

Saya adalah pengembang PHP. PHP tidak menyenangkan untuk diketik.

Who::in::their::right::mind::would::do::this()? The ::Operator membutuhkan holding shift dan kemudian dua tombol yang ditekan. Buang-buang energi.

Meskipun-> ini-> tidak-> jauh-> lebih baik. Itu juga membutuhkan tiga penekanan tombol dengan pergeseran berada di antara dua simbol.

$last = $we.$have.$the.$dumb.'$'.$character. Tanda dolar digunakan dalam jumlah yang luar biasa besar dan membutuhkan peregangan penghargaan hingga ke bagian paling atas keyboard plus tombol shift.

Mengapa mereka tidak bisa mendesain PHP untuk menggunakan kunci yang lebih cepat diketik? Mengapa we.do.this()vars tidak dapat atau mulai dengan kunci yang hanya memerlukan penekanan tombol tunggal - atau tidak sama sekali (JavaScript) dan tentukan sebelumnya semua vars (seperti yang harus saya lakukan untuk E_STRICT)!

Saya bukan pengetik yang lambat - tapi ini hanya pilihan desain yang lemah.

Xeoncross
sumber
Perl berbagi rasa sakit ini.
Daenyth
2
Begitu juga C ++, dan untuk beberapa alasan aneh yang tidak bisa dijelaskan, PowerShell.
Rei Miyasaka
2
Gunakan editor yang lebih kuat, dan tentukan urutan kunci Anda sendiri untuk operator tersebut.
kevin cline
1
I::have::nothing::against::this->at.all()
Mateen Ulhaq
1
Mungkin mereka tidak menggunakan keyboard qwerty. $ dan: tidak perlu tombol shift ditekan pada semua keyboard seperti azerty.
Arkh
13

Penggunaan formulir yang terinspirasi desktop dalam asp.net .

Itu selalu terasa fudge dan menghalangi atau bagaimana web sebenarnya bekerja. Syukurlah asp.net-mvc tidak menderita dengan cara yang sama, meskipun dengan kredit untuk Ruby dll untuk inspirasi itu.

merpati
sumber
18
Bukankah itu hal perpustakaan?
nikie
@nikie itu poin yang bagus;)
dove
1
@nikie Sebenarnya, kode ASPX berbasis XML adalah bahasa, sehingga Anda dapat memutar yang ini untuk bekerja. : D
CodexArcanum
2
Masalah sebenarnya dengan ASP.NET, saya pikir, adalah betapa sulitnya mencoba untuk menyembunyikan detail web dari programmer. Sebenarnya ada beberapa hal yang benar-benar rapi dan berguna terjadi di ASP.NET, tetapi Anda harus berjuang begitu keras dan menggali begitu dalam untuk mendapatkannya.
CodexArcanum
1
Di sisi lain ada ribuan dan ribuan aplikasi pengumpulan data yang sederhana dan sukses di luar sana yang menggabungkan penggunaan aplikasi desktop "klasik". Satu-satunya hal yang buruk adalah bahwa sampai MVC satu-satunya pilihan Microsoft adalah bentuk windows.
ElGringoGrande
13

Bagi saya itu adalah kurangnya konvensi penamaan dan argumen pemesanan PHP di perpustakaan standarnya.

Meskipun kebutuhan JASS untuk membatalkan referensi setelah objek yang direferensikan dirilis / dihapus (atau referensi akan bocor dan beberapa byte memori akan hilang) lebih serius, tetapi karena JASS adalah bahasa tujuan tunggal, itu tidak terlalu kritis.

Matěj Zábský
sumber
9
Kurangnya konvensi dalam stdlib PHP bisa dibilang bukan cacat desain bahasa .
3
@delnan: Kurangnya konvensi adalah hasil dari bagaimana PHP dirancang, dan karena itu banyak berhubungan dengan desain bahasa. Juga tidak jelas bagi saya bahwa ada perbedaan yang jelas antara perpustakaan dan bahasa. Khususnya Lisp memiliki tradisi bangga dengan bootstrap satu bahasa di atas yang lain.
btilly
1
Hal yang benar-benar luar biasa tentang JASS adalah bahwa ia memiliki referensi yang mengandalkan pegangan, tetapi tidak akan membersihkannya kecuali jika dihancurkan secara manual (dan antarmuka grafis menciptakan fungsi yang membocorkan memori di mana-mana)!
Craig Gidney
13

Cacat desain terbesar yang saya hadapi adalah bahwa python tidak dirancang seperti python 3.x untuk memulai.

dan_waterworth
sumber
1
Ya, bahkan Guido tidak bisa menyelesaikan semuanya sekaligus ...
5
@delnan, oh saya tahu, dan python <3 masih merupakan bahasa yang sangat bagus, tetapi agak menyebalkan memiliki bahasa yang lebih baik dalam bentuk python 3.x yang tidak dapat saya gunakan karena ia merusak semua modul yang Saya butuh.
dan_waterworth
Terus melobi modul python 3.x Anda! Sementara itu saya akan terus menulis dalam 2.5.4. Berkat SO saya benar-benar diingatkan bahwa 3.x hidup dan sehat.
kevpie
@ kevpie Pertama, lobi untuk menambahkan kompilasi bersyarat ke python untuk membuat transisi lebih mudah bagi pengelola perpustakaan. 2to3 bukan solusi yang bisa dipertahankan dalam jangka panjang.
Evan Plaice
12

Array pembusukan dalam C dan akibatnya C ++.

Nemanja Trifunovic
sumber
Saya berharap untuk dukungan array yang tepat juga. Dalam C ++ Anda dapat mencegah pembusukan menggunakan sintaks dan templat abscons ... tetapi ini lebih merupakan peretasan: /
Matthieu M.
1
Perhatikan bahwa ini adalah alasan bahwa C ++ harus memiliki operator deletedan terpisah delete[].
dan04
Anda selalu dapat meletakkan array ke dalam struct dan membagikannya dengan nilai jika Anda suka, tetapi ini biasanya lebih canggung daripada masalah aslinya. Di C ++, Anda biasanya dapat menghindari kebutuhan untuk menggunakan array.
David Thornley
2
Setidaknya dalam kasus C, argumen terhadap dukungan array yang tepat adalah "pemeriksaan batas array mahal", terutama mengingat cara aritmatika pointer C bekerja.
Stephen C
@Stephen C: Apa hubungannya batas array memeriksa dengan peluruhan array?
Nemanja Trifunovic
11

Jenis primitif di Jawa.

Mereka melanggar prinsip bahwa segala sesuatu adalah turunan dari java.lang.Object, yang dari sudut pandang teoretis mengarah ke kompleksitas tambahan dari spesifikasi bahasa, dan dari perspektif praktis mereka membuat penggunaan koleksi sangat membosankan.

Autoboxing membantu meringankan kekurangan praktis tetapi dengan biaya membuat spesifikasi lebih rumit dan memperkenalkan kulit pisang besar lemak: sekarang Anda bisa mendapatkan pengecualian pointer nol dari apa yang tampak seperti operasi aritmatika sederhana.

biziclop
sumber
Ini akan menyebabkan masalah kinerja yang buruk jika Anda menghapus tipe primitif. Dan autoboxing dapat dikacaukan dengan cukup mudah, sehingga tidak meningkatkan apa pun.
deadalnix
Pada saat itu, ini adalah keputusan yang masuk akal dari para desainer Java. Keuntungan kinerja yang diberikan mesin / VMs yang tersedia di tahun 90-an melebihi keunggulan konseptual dari menyatukan segala sesuatu di sekitar java.lang.Object.
mikera
10

Saya tahu Perl terbaik, jadi saya akan memilihnya.

Perl mencoba banyak ide. Beberapa bagus. Ada yang buruk. Beberapa asli dan tidak disalin secara luas karena alasan yang baik.

Salah satunya adalah gagasan tentang konteks - setiap pemanggilan fungsi dilakukan dalam daftar atau konteks skalar, dan dapat melakukan hal-hal yang sepenuhnya berbeda dalam setiap konteks. Seperti yang saya tunjukkan di http://use.perl.org/~btilly/journal/36756 hal ini menyulitkan setiap API, dan sering menyebabkan masalah desain yang halus dalam kode Perl.

Yang berikutnya adalah ide untuk mengikat sintaks dan tipe data secara lengkap. Ini mengarah pada penemuan dasi untuk memungkinkan objek untuk menyamar sebagai tipe data lainnya. (Anda juga dapat mencapai efek yang sama menggunakan overload, tetapi dasi adalah pendekatan yang lebih umum di Perl.)

Kesalahan umum lainnya, yang dibuat oleh banyak bahasa, adalah memulai dengan menawarkan pelingkupan dinamis daripada leksikal. Sulit untuk mengembalikan keputusan desain ini nanti, dan mengarah pada kutil yang tahan lama. Deskripsi klasik dari kutil tersebut di Perl adalah http://perl.plover.com/FAQs/Namespaces.html . Perhatikan bahwa ini ditulis sebelum Perl menambahkan ourvariabel dan staticvariabel.

Orang-orang secara sah tidak setuju pada pengetikan statis versus dinamis. Saya pribadi suka mengetik dinamis. Namun penting untuk memiliki struktur yang cukup untuk membiarkan kesalahan ketik ditangkap. Perl 5 melakukan pekerjaan dengan baik dengan ketat. Tapi Perl 1-4 salah. Beberapa bahasa lain memiliki checker yang melakukan hal yang sama dengan ketat. Selama Anda pandai menegakkan pemeriksaan serat, itu bisa diterima.

Jika Anda mencari lebih banyak ide buruk (banyak di antaranya), pelajari PHP dan pelajari sejarahnya. Kesalahan masa lalu favorit saya (sudah lama diperbaiki karena menyebabkan banyak lubang keamanan) adalah default untuk mengizinkan siapa saja untuk mengatur variabel apa pun dengan mengirimkan parameter formulir. Tapi itu jauh dari satu-satunya kesalahan.

btilly
sumber
5
Ya, Perl memiliki banyak kesalahan, karena orang-orang yang membangunnya mencoba ide-ide baru, dan ketika Anda melakukan itu, Anda sering salah. (Perl juga memiliki beberapa hal yang sangat bagus, dan merupakan standar untuk Regexps yang tampaknya telah disalin oleh semua orang)
Zachary K
@ zachary-k: Sepenuhnya disetujui. Dan saya mencoba menjelaskannya sebelum saya mulai membahas masalah.
btilly
4
Lisps awalnya dibatasi secara dinamis, dan seiring waktu berubah menjadi lingkup leksikal (setidaknya dalam Skema dan Common Lisp). Bukan tidak mungkin untuk berubah.
David Thornley
4
@ david-thornley: Tidak mungkin kecuali Anda mengorbankan kompatibilitas di suatu tempat. Skema selalu dibatasi secara leksikal. Lisp umum dilindungi secara leksikal sejak standar, tetapi berbagai komunitas Lisp memiliki perjuangan untuk mengadopsinya. Dan Emacs Lisp masih menggunakan pelingkupan dinamis, meskipun telah ada keinginan untuk mengubahnya untuk waktu yang lama.
btilly
1
BTW, banyak hal yang orang tidak suka Perl tidak ditemukan dalam Perl tetapi diambil dari bahasa lain, kebanyakan shell Bourne.
reinierpost
10

Ambiguitas JavaScripts untuk blok kode dan objek literal.

  {a:b}

bisa berupa blok kode, di mana alabel dan bekspresi; atau bisa mendefinisikan objek, dengan atribut ayang memiliki nilaib

pengguna281377
sumber
Saya sebenarnya suka ini tentang JavaScript. Kesederhanaan struktur bahasa itu bagus dan tujuannya harus jelas jika pengembang tahu apa yang mereka lakukan.
Xeoncross
2
Xeoncross: Saya umumnya tidak suka ambiguitas. Dalam hal ini, jelas bagi pengembang, tetapi eval () membutuhkan tanda kurung tambahan.
user281377
2
@ammoQ: Sudah jelas? Lalu apa itu? Objek atau blok kode?
konfigurator
konfigurator: Jelas sebuah objek. Tidak ada orang waras yang menggunakan label yang disebut a.
user281377
10

Aku akan kembali ke FORTRAN dan ketidakpekaan whitespace.

Itu meliputi spesifikasi. The ENDkartu harus didefinisikan sebagai kartu dengan 'E', sebuah 'N', dan 'D' agar di kolom 7-72, dan tidak ada Nonblanks lain, daripada kartu dengan "END" di tepat kolom dan tidak ada yang lain.

Itu menyebabkan kebingungan sintaksis yang mudah. DO 100 I = 1, 10adalah pernyataan kontrol loop, sedangkan DO 100 I = 1. 10pernyataan yang menetapkan nilai 1.1 ke variabel yang dipanggil DO10I. (Fakta bahwa variabel dapat dibuat tanpa deklarasi, tipenya tergantung pada huruf pertama mereka, berkontribusi terhadap hal ini.) Tidak seperti bahasa lain, tidak ada cara untuk menggunakan spasi untuk memisahkan token untuk memungkinkan disambiguasi.

Itu juga memungkinkan orang lain untuk menulis kode yang benar-benar membingungkan. Ada alasan mengapa fitur FORTRAN ini tidak pernah digandakan lagi.

David Thornley
sumber
1
Dalam bahasa di mana Anda dapat mendefinisikan kembali literal, itu adalah contoh terburuk - maksud saya hanya menyebabkan satu pesawat ruang angkasa kecil hancur
Martin Beckett
Awalnya, Anda bisa menulis DAMNATION sebagai pengganti DIMENSION, dan itu akan berhasil.
Mike Dunlavey
Itu masih diajarkan, oleh orang-orang di luar CS. Saya masih harus berurusan dengan mereka yang a) bertempur melawan deklarasi, b) bertempur melawan spasi, c) seperti "garis kelanjutan", d) menggunakan nama 6-karakter, atau 4, d) bingung ketika mereka melihat (test ? a : b), e) bersikeras saat menggunakan **, f) tidak dapat menangani sensitivitas huruf besar-kecil. Sebagian besar ini adalah karena tombol pada tahun 50-an.
Mike Dunlavey
1
@ Martin Beckett - mendefinisikan kembali literal dalam FORTRAN benar-benar kelemahan kompiler daripada fitur bahasa. Jelas itu bukan fitur bahasa yang disengaja.
Stephen C
1
@ Oosterwal: Tentu saja saya lakukan. Saya mungkin salah, tapi saya samar-samar ingat definisi bahasa berdasarkan kartu punch. Mereka adalah cara utama memasukkan program FORTRAN saat itu, dan gagasan garis 80-kolom dengan kolom 73-80 disediakan dari kartu punch.
David Thornley
9

Salah satu masalah terbesar dengan BASIC adalah kurangnya metode yang terdefinisi dengan baik untuk memperluas bahasa di luar lingkungan awalnya, yang mengarah ke sekelompok implementasi yang sama sekali tidak kompatibel (dan upaya pasca-facto yang hampir tidak relevan pada standardisasi apa pun).

Hampir semua bahasa akan digunakan untuk tujuan umum oleh beberapa programmer gila. Lebih baik untuk merencanakan penggunaan tujuan umum di awal jika ide gila lepas landas.

hotpaw2
sumber
2
+1: Bahasa apa pun tanpa modul dan perpustakaan yang tepat adalah kesalahan yang menunggu untuk terjadi. COBOL juga menderita hal ini, yang mengarah ke varian aneh yang tidak kompatibel.
S.Lott
8

Saya percaya pada DSL (domain-spesifik-bahasa) dan satu hal yang saya hargai dalam suatu bahasa adalah jika memungkinkan saya untuk mendefinisikan DSL di atasnya.

Di Lisp ada makro - kebanyakan orang menganggap ini hal yang baik, seperti halnya saya.

Di C dan C ++ ada makro - orang mengeluh tentang mereka, tapi saya bisa menggunakannya untuk mendefinisikan DSL.

Di Jawa, mereka ditinggalkan (dan karena itu dalam C #), dan kekurangan mereka dinyatakan sebagai kebajikan. Tentu itu memungkinkan Anda memiliki kecerdasan, tetapi bagi saya itu hanya sebuah oeuvre . Untuk melakukan DSL saya, saya harus melakukan ekspansi dengan tangan. Ini menyebalkan, dan itu membuat saya terlihat seperti seorang programmer yang buruk, walaupun itu membuat saya melakukan lebih banyak hal dengan lebih sedikit kode.

Mike Dunlavey
sumber
4
Saya setuju bahwa bahasa apa pun tanpa makro yang layak adalah cacat desain yang tidak bisa diperbaiki. Tapi apa yang Anda maksud dengan ' mereka ditinggalkan '? C preprocessor bukan jenis sistem makro yang layak. Java tidak berasal dari bahasa yang tepat dengan makro.
SK-logic
1
Anda dapat menulis DSL Anda dalam bahasa pemrosesan makro eksternal (seperti m4, katakanlah, di antara banyak lainnya).
HANYA SAYA PENDAPAT benar
4
@ SK: Saya tidak akan mengatakan C preprocessor adalah sistem makro yang layak dibandingkan dengan Lisp (misalnya). Tetapi, dibandingkan dengan tidak sama sekali , ini sangat berguna.
Mike Dunlavey
4
@reinierpost: Saya memikirkan hal-hal yang dapat saya lakukan di Lisp, seperti memperkenalkan struktur kontrol seperti eksekusi diferensial dan mundur. Ini bisa dilakukan dengan macro Lisp. Dalam C / C ++ saya bisa melakukan eksekusi diferensial dengan makro C (dan sedikit disiplin programmer), tetapi tidak mundur. Dengan C # saya tidak bisa melakukan keduanya. Yang saya dapatkan sebagai gantinya adalah hal-hal seperti intellisense. BFD.
Mike Dunlavey
1
@ David: Cara saya melakukannya adalah saya memiliki makro untuk membungkus kode biasa, seperti daftar pernyataan. Itu akan mengambil cdrdaftar dan membentuk penutupan lambda dari itu (yaitu kelanjutan) dan meneruskannya sebagai argumen ke cardaftar. Itu dilakukan secara rekursif, tentu saja, dan akan "melakukan hal yang benar" untuk kondisional, loop, dan pemanggilan fungsi. Kemudian fungsi "pilihan" baru saja berubah menjadi loop normal. Tidak cantik, tapi kuat. Masalahnya, itu membuatnya sangat mudah untuk membuat loop yang terlalu bersarang.
Mike Dunlavey
7

Pernyataan , dalam setiap bahasa yang memilikinya. Mereka tidak melakukan apa pun yang tidak dapat Anda lakukan dengan ekspresi dan mencegah Anda melakukan banyak hal. Keberadaan ?:operator ternary hanyalah salah satu contoh harus mencoba untuk berkeliling mereka. Dalam JavaScript, mereka sangat menjengkelkan:

// With statements:
node.listen(function(arg) {
  var result;
  if (arg) {
    result = 'yes';
  } else {
    result = 'no';
  }
  return result;
})

// Without:
node.listen(function(arg) if (arg) 'yes' else 'no')
munificent
sumber
Saya bingung di sini: Apakah Anda hanya ingin cara yang lebih sederhana untuk melakukan sesuatu?
TheLQ
2
Benar. Ekspresi untuk semuanya.
murah hati
1
Lisp bekerja dengan baik untuk ini.
David Thornley
1
@ SK-logika: Saya menduga bahwa pernyataan secara acak diwarisi dari bahasa mesin, melalui FORTRAN, ALGOL, dan COBOL.
David Thornley
1
Saya cukup yakin bahasa mesin adalah leluhur yang umum, dan itu hanya cerminan dari fakta bahwa komputer modern berdasarkan arsitektur von Neumann menjalankan instruksi secara berurutan dan memodifikasi keadaan. Pada akhirnya ketika IO terjadi, akan ada ekspresi yang tidak menghasilkan data yang bermakna, sehingga pernyataan tidak sepenuhnya berguna dalam mengindikasikan secara semantik bahwa beberapa kode hanya memiliki efek samping. Bahkan bahasa yang memiliki gagasan unittipe (alias ()) alih-alih pernyataan memiliki pertimbangan khusus untuk memastikan bahwa mereka tidak memberikan peringatan atau berperilaku aneh.
Rei Miyasaka
6

Bagi saya, itu adalah masalah desain yang mengganggu semua bahasa yang berasal dari C; yaitu, " menggantung yang lain ." Masalah tata bahasa ini seharusnya telah diselesaikan dalam C ++, tetapi dibawa ke Java dan C #.

fretje
sumber
3
Salah satu tujuan inti dari C ++ adalah untuk sepenuhnya kompatibel dengan C. Jika mereka telah mengubah perilaku semantik secara drastis, itu mungkin tidak menarik seperti yang terjadi (atau setidaknya, itulah pemikiran pada saat itu)
Ed S.
2
@ Ed S., namun, penghapusan masalah "menggantung lain" bisa diselesaikan dengan menghilangkan <compound_statement> (alias <block>) produksi tata bahasa dan memasukkan kurung kurawal ke dalam struktur kontrol bersyarat dan berulang seperti yang mereka lakukan ketika mereka menambahkan struktur kontrol penanganan mencoba / menangkap pengecualian. Tidak ada alasan untuk tidak memperbaiki ambiguitas tata bahasa ini di Jawa dan C #. Saat ini, pekerjaan defensif untuk ambiguitas tata bahasa ini adalah membuat setiap pernyataan yang mengikuti pernyataan kontrol bersyarat atau berulang menjadi pernyataan majemuk.
bit-twiddler
1
Bagaimana apanya? Ini bukan "masalah tata bahasa" (itu sama sekali tidak ambigu). Bagaimana Anda “menyelesaikannya”? Saya benar-benar menemukan aturan dalam C memuaskan. Boleh dibilang, hanya sintaks seperti-Python (= indentasi bermakna) yang benar-benar dapat menyelesaikan masalah ini. Selain itu, saya sebenarnya sangat senang bahwa bahasa modern tidak membutuhkan kawat gigi. Saya setuju bahwa semua sintaks mirip-C menghisap tetapi menggantung-yang lain adalah yang paling sedikit dari masalah mereka.
Konrad Rudolph
1
Melanjutkan: Saya pikir bahwa penggunaan lekukan Python sebagai sarana untuk menggambarkan daftar pernyataan adalah aneh di luar kepercayaan. Teknik ini melanggar prinsip "pemisahan keprihatinan" dengan pemindaian leksikal yang erat dengan analisis sintaksis. Tata bahasa bebas konteks harus dapat diurai tanpa mengetahui apapun tentang tata letak sumber.
bit-twiddler
3
@ bit-twiddler: Tidak, tidak. Python lexer baru saja mengonversi spasi putih ke token INDENT dan DEDENT yang sesuai. Setelah selesai, Python memiliki tata bahasa yang cukup konvensional ( docs.python.org/reference/grammar.html ).
dan04
6

Saya pikir semua jawaban sejauh ini menunjuk pada satu kegagalan banyak bahasa utama:

Tidak ada cara untuk mengubah bahasa inti tanpa mempengaruhi kompatibilitas ke belakang.

Jika ini diselesaikan maka hampir semua keluhan lain dapat diselesaikan.

EDIT.

ini dapat diselesaikan di perpustakaan dengan memiliki ruang nama yang berbeda, dan Anda dapat membayangkan melakukan sesuatu yang serupa untuk sebagian besar inti bahasa, meskipun ini mungkin berarti Anda perlu mendukung banyak kompiler / juru bahasa.

Pada akhirnya saya tidak berpikir saya tahu bagaimana menyelesaikannya dengan cara yang benar-benar memuaskan, tetapi itu tidak berarti solusi tidak ada, atau lebih banyak yang tidak dapat dilakukan

jk.
sumber
1
Bagaimana Anda akan "memecahkan" ini?
Bjarke Freund-Hansen
Saya tidak yakin ini bisa sepenuhnya diselesaikan - jelas menjaga hal-hal keluar dari bahasa inti dan di perpustakaan standar membantu jadi saya pikir saya akan mencoba mendorong ini sejauh mungkin
jk.
1
Dengan kompatibel mundur, maksud Anda kompiler baru harus dapat mengkompilasi kode lama?
Rei Miyasaka
Maksudku kompiler baru tidak boleh mengubah arti kode lama, gagal mengkompilasi akan menjadi bagian dari itu
jk.
sebagian besar kasus, ketika fitur tertentu tidak ada, atau ingin diubah, orang membuat bahasa baru berdasarkan yang sebelumnya. C dengan kelas => C ++
umlcat
4

Java integer diam meluap aritmatika

fretje
sumber
4
Java jauh dari bahasa pertama yang memiliki fitur itu.
dan04
@ dan04 Ini adalah fitur yang sangat bagus, bukan?
Mateen Ulhaq
4

Baik Java dan C # memiliki masalah yang mengganggu dengan sistem tipe mereka karena keinginan untuk mempertahankan kompatibilitas sambil menambahkan obat generik. Java tidak suka mencampur generik dan array; C # tidak akan mengizinkan beberapa tanda tangan yang berguna karena Anda tidak dapat menggunakan tipe nilai sebagai batas.

Sebagai contoh dari yang terakhir, pertimbangkan itu

public T statis Parse <T> (Ketik tipe <T>, string str) di mana T: Enum
bersama atau mengganti
Parse objek statis publik (Jenis tipe, string str)
di Enumkelas akan memungkinkan
MyEnum e = Enum.Parse (typeof (MyEnum), str);
daripada tautologis
MyEnum e = (MyEnum) Enum.Parse (typeof (MyEnum), str);

tl; dr: pikirkan polimorfisme parametrik ketika Anda mulai merancang sistem tipe Anda, bukan setelah Anda menerbitkan versi 1.

Peter Taylor
sumber
2
Ketidakmampuan untuk membatasi jenis enum mengganggu dalam C #, tetapi Anda dapat jenis mengatasinya seperti ini MyMethod<T>(T value) where T : struct, IComparable, IFormattable, IConvertible Tapi Anda masih harus menguji untuk enum dan itu adalah peretasan. Saya pikir kekurangan yang lebih besar dalam generik C # tidak ada dukungan untuk jenis yang lebih tinggi, yang benar-benar akan membuka bahasa untuk beberapa konsep keren.
CodexArcanum
4

Saya merasa seperti membuka diri untuk dinyalakan, tetapi saya benar-benar benci kemampuan untuk melewatkan tipe data lama dengan merujuk pada C ++. Saya hanya sedikit benci bisa melewati tipe kompleks dengan referensi. Jika saya melihat suatu fungsi:

void foo()
{
    int a = 8;
    bar(a);
}

Dari titik panggilan, tidak ada cara untuk mengatakan bahwa bar, yang dapat didefinisikan dalam file yang sama sekali berbeda, adalah:

void bar(int& a)
{
    a++;
}

Beberapa orang mungkin berpendapat bahwa melakukan sesuatu seperti ini mungkin hanya desain perangkat lunak yang buruk, dan tidak bisa menyalahkan bahasa, tetapi saya tidak suka bahasanya memungkinkan Anda melakukan ini sejak awal. Menggunakan pointer dan panggilan

bar(&a);

jauh lebih mudah dibaca.

Jeff
sumber
+1 Saya tidak setuju dengan Anda, tetapi saya menghargai alasan Anda.
Jon Purdy
@ Jon Saya sebenarnya sangat tertarik pada apa yang Anda pikirkan. Apakah Anda memiliki pandangan "jangan salahkan bahasa"?
Jeff
6
@ Jeff: Untuk satu hal, alasan utama semantik referensi masuk ke C ++ adalah operator overloading, yang mana perilaku referensi seragam cukup masuk akal. Lebih penting lagi, C ++ dirancang untuk serbaguna dan menyediakan fitur yang sangat halus, bahkan jika hal itu menimbulkan risiko kesalahan programmer yang signifikan. Jadi ya, setidaknya dalam kasus khusus ini, jangan salahkan bahasanya. Saya lebih suka bisa membuat kesalahan daripada membiarkan bahasa menghalangi saya.
Jon Purdy
@ Jon setuju, itu akan sangat aneh untuk referensi lewat berlaku untuk segala sesuatu selain POD. Saya lebih suka jika fitur ini hilang sepenuhnya dari C ++ sebagai alternatif, tetapi kami dapat setuju untuk tidak setuju :). Terima kasih atas masukannya!
Jeff
Java tampaknya tidak suka pointer sebanyak yang Anda lakukan.
Mateen Ulhaq
4

MENGUBAH

Ketika saya belajar COBOL, pernyataan ALTER masih menjadi bagian dari standar. Singkatnya, pernyataan ini akan memungkinkan Anda untuk memodifikasi panggilan prosedur saat runtime.

Bahayanya adalah Anda bisa meletakkan pernyataan ini di bagian kode yang tidak jelas yang jarang diakses dan berpotensi mengubah aliran program Anda secara keseluruhan. Dengan beberapa pernyataan ALTER, Anda dapat membuatnya hampir mustahil untuk mengetahui apa yang sedang dilakukan program Anda kapan saja.

Instruktur universitas saya, dengan sangat tegas, menyatakan bahwa jika ia pernah melihat pernyataan itu dalam program kami, ia akan secara otomatis membuat kami gagal.

oosterwal
sumber
Itu memang memiliki kasus penggunaan yang baik - stubbing atau memoization. Alih-alih menulis v() { if (not alreadyCalculatedResult) { result = long(operation); alreadyCalculatedResult = true; } result; }Anda katakanv() { result = long(operation); v = () => result; result; }
konfigurator
4

Dosa terburuk dari bahasa pemrograman tidak didefinisikan dengan baik. Sebuah kasus yang saya ingat adalah C ++, yang, asalnya:

  1. Sangat tidak jelas sehingga Anda tidak bisa membuat program untuk dikompilasi dan dijalankan dengan mengikuti buku atau contoh.
  2. Setelah Anda men-tweak program untuk dikompilasi dan dijalankan di bawah satu kompiler dan OS, Anda harus memulai dari awal jika Anda mengganti kompiler atau platform.

Seingat saya, butuh sekitar satu dekade untuk mendapatkan C ++ yang didefinisikan dengan cukup baik untuk menjadikannya dapat diandalkan secara profesional seperti C. Ini adalah sesuatu yang seharusnya tidak pernah terjadi lagi.

Hal lain yang saya anggap dosa (haruskah ia pergi dalam jawaban yang berbeda?) Adalah memiliki lebih dari satu cara "terbaik" untuk melakukan beberapa tugas bersama. Ini adalah kasus dari (lagi) C ++, Perl, dan Ruby.

Apalala
sumber
1
Saya tidak melihat bagaimana cara menghindari kesalahan definisi dalam bahasa yang berkembang. Atau, dalam hal ini, dalam bahasa yang dirancang sebelumnya di mana desainer asli melewatkan beberapa poin penting (seperti Pascal).
David Thornley
@ David Thornley Definisi yang jelas didefinisikan dengan baik. Dengan bug yang tahan, sebagian besar perancang bahasa pemrograman melakukannya sejak awal. Alat dapat memeriksa bahwa tata bahasa tidak ambigu ketika selesai (C ++ membutuhkan setidaknya tiga tata bahasa), dan semantik harus untuk implementasi standar harus ditentukan.
Apalala
Saya setuju bahwa bahasa yang didefinisikan dengan baik adalah mungkin, tetapi itu tidak akan terjadi dalam bahasa yang berkembang seperti pra-Standar C ++. Alternatifnya adalah bahwa setiap bahasa dirancang secara menyeluruh sebelum dirilis, dan itu belum tentu cara untuk mendapatkan bahasa terbaik. Saya akan mengatakan bahwa sebagian besar desainer bahasa pemrograman membuat kesalahan pada awalnya, karena desain bahasa sangat rumit.
David Thornley
Saya kira saya mengalami kesulitan memahami apa yang Anda maksud dengan "didefinisikan dengan baik". Apakah keluhan Anda bahwa kompiler C ++ berbeda sebenarnya tidak mengkompilasi bahasa yang sama?
Sean McMillan
3

Kelas-kelas di C ++ adalah semacam pola desain paksa dalam bahasa.

Praktis tidak ada perbedaan pada saat runtime antara struct dan kelas, dan itu sangat membingungkan untuk memahami apa sebenarnya keunggulan pemrograman "penyembunyian informasi" yang ingin saya taruh di sana.

Saya akan downvoted untuk itu, tapi bagaimanapun, kompiler C ++ sangat sulit untuk menulis bahasa ini terasa seperti monster.

jokoon
sumber
2
Penyembunyian informasi penting karena memungkinkan Anda menyembunyikan detail spesifik implementasi, yang kemungkinan akan berubah, dari bagian API yang dapat diakses ("UI" API) sehingga membuat perubahan pada program menjadi lebih mudah dan tidak menyakitkan.
Anto
1
UI API ... tidak, serius, saya tidak membelinya.
jokoon
3
Perbedaan ini bukan bagian yang paling menjijikkan dari C ++, bahkan tidak dekat. Satu-satunya perbedaan adalah pengubah akses default (publik untuk struct, pribadi untuk kelas). C ++ adalah bahasa yang mengerikan, mengerikan, tetapi tentu saja tidak di bagian ini.
SK-logic
sk-logic: well, saya bisa mengatakan kengerian mulai dari sana.
jokoon
2
Menyembunyikan informasi itu baik; Anda dapat menemukan diskusi tentang itu di mana-mana. Satu-satunya buku perangkat lunak terkemuka yang dapat saya pikirkan yang menentangnya adalah buku Brooks "The Mythical Man-Month", dan dia kemudian menganggapnya sebagai kesalahan terbesar dalam buku tersebut. Jika Anda tidak memahami kelebihannya, Anda benar-benar tidak memenuhi syarat untuk membuat penilaian yang Anda buat.
David Thornley
3

Meskipun setiap bahasa memiliki kesalahan, tidak ada gangguan setelah Anda mengetahuinya. Kecuali untuk pasangan ini:

Sintaks yang rumit ditambah dengan API bertele-tele

Ini terutama berlaku untuk bahasa seperti Objective-C. Sintaksnya tidak hanya sangat kompleks, tetapi API menggunakan nama fungsi seperti:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

Saya semua untuk menjadi eksplisit dan tidak ambigu, tetapi ini konyol. Setiap kali saya duduk dengan xcode, saya merasa seperti n00b, dan itu benar-benar membuat frustrasi.

Dimitry
sumber
Sintaks Objective-C sangat kompleks? Apakah Anda tidak melihat C ++? Dan nama metode sebenarnya ada tableView:cellForRowAtIndexPath:, yang sangat deskriptif menurut saya.
rightfold
Belajar mengetik.
finnw
2
  1. menandatangani karakter di C - sebuah kekejian yang diciptakan untuk membiarkan matematikawan memiliki koleksi besar barang-barang kecil
  2. Menggunakan case untuk membawa konten semantik - lagi untuk ahli matematika, yang tidak perlu bicara , dan tidak pernah memiliki cukup ruang untuk formula mereka
  3. Biarkan / Tugas polos vs. Menetapkan tugas dalam dialek Dasar - saya pikir tidak ada ahli matematika yang terlibat di sini
Ekkehard.Horner
sumber
Saya bingung dengan komentar karakter yang Anda tanda tangani, dapatkah Anda menjelaskan?
Winston Ewert
1
Bagi manusia, konsep (tidak) karakter yang ditandatangani dan keharusan untuk memberitahu kompiler untuk menggunakan karakter yang tidak ditandatangani sebagai default pasti sama gilanya dengan pernyataan ahli matematika bahwa 2! = 2, karena 2 yang kedua adalah huruf besar, tebal , atau miring.
Ekkehard.Horner
5
Masalahnya adalah bahwa C mengacaukan konsep "char" (yaitu, bagian dari string teks) dan "byte" (yaitu, (u)int_least8_t). Signedness masuk akal untuk bilangan bulat kecil, tetapi sama sekali tidak masuk akal untuk karakter.
dan04
@ dan04: Saya setuju, saya berharap mereka memiliki tipe berbeda untuk integer kecil (ditandatangani dan tidak ditandatangani), byte dan karakter. Ketika Anda menjelaskan kepada pemula bahwa untuk memanipulasi memori mentah yang mereka butuhkan untuk melemparkan ke char*... seperti C-String, mereka menjadi sangat bingung.
Matthieu M.
C # punya hak ini dengan terpisah sbyte, bytedan charjenis.
dan04