Apa yang dilakukan C ++ lebih baik daripada D?

135

Saya baru-baru ini belajar D dan mulai mendapatkan semacam keakraban dengan bahasa. Saya tahu apa yang ditawarkannya, saya belum tahu bagaimana menggunakan semuanya, dan saya tidak tahu banyak tentang idiom D dan sebagainya, tetapi saya sedang belajar.

Saya suka D. Ini adalah bahasa yang bagus, karena, dalam beberapa hal, pembaruan besar ke C, dan dilakukan dengan baik. Tidak ada fitur yang tampak "melesat", tetapi sebenarnya cukup dipikirkan dan dirancang dengan baik.

Anda akan sering mendengar bahwa D adalah apa C ++ harus sudah (saya meninggalkan pertanyaan apakah atau tidak itu benar kepada setiap orang untuk memutuskan diri untuk menghindari perang api yang tidak perlu). Saya juga telah mendengar dari beberapa programmer C ++ bahwa mereka menikmati D lebih dari C ++.

Saya sendiri, sementara saya tahu C, saya tidak bisa mengatakan bahwa saya tahu C ++. Saya ingin mendengar dari seseorang yang mengetahui C ++ dan D jika mereka berpikir ada sesuatu yang C ++ lakukan lebih baik daripada D sebagai bahasa (artinya bukan yang biasa "ia memiliki lebih banyak perpustakaan pihak ketiga" atau "ada lebih banyak sumber daya" atau " lebih banyak pekerjaan yang membutuhkan C ++ daripada D ada ").

D dirancang oleh beberapa programmer C ++ yang sangat terampil ( Walter Bright dan Andrei Alexandrescu , dengan bantuan komunitas D) untuk memperbaiki banyak masalah yang dimiliki C ++, tetapi apakah ada sesuatu yang sebenarnya tidak menjadi lebih baik? Sesuatu yang dia lewatkan? Sesuatu yang Anda pikir bukan solusi yang lebih baik?

Juga, perhatikan bahwa saya berbicara tentang D 2.0 , bukan D 1.0 .

Anto
sumber
15
Saya memastikan komunitas D tidak melihat ini karena saya yakin ada jauh lebih banyak C ++ devs daripada D devs di sekitar sini. Dengan begitu Anda akan memiliki jawaban yang lebih menarik atau setidaknya beragam.
Klaim
7
Juga, D2 dirancang oleh Walter Bright tetapi juga dengan Alexandrescu. Anda mungkin ingin memperbaikinya dalam pertanyaan Anda.
Klaim
2
@Klaim: ada (dan masih) banyak keterlibatan masyarakat dalam D dan perpustakaan standar juga.
Michal Minich
28
@Anto Sebagai bahasa, C ++ jauh lebih baik daripada D dalam membuat Anda, programmer, membenci hidup Anda.
Arlen
6
@jokoon: Sebenarnya, ya, dengan sedikit kerja: digitalmars.com/d/2.0/interfaceToC.html
Anto

Jawaban:

124

Sebagian besar hal yang C ++ "lakukan" lebih baik daripada D adalah hal-hal meta: C ++ memiliki kompiler yang lebih baik, alat yang lebih baik, perpustakaan yang lebih matang, lebih banyak binding, lebih banyak ahli, lebih banyak tutorial, dll. Pada dasarnya ia memiliki lebih banyak dan lebih baik dari semua hal eksternal yang Anda harapkan dari bahasa yang lebih matang. Ini tidak bisa dibantah.

Adapun bahasa itu sendiri, ada beberapa hal yang C ++ tidak lebih baik daripada D menurut saya. Mungkin ada lebih banyak, tetapi ada beberapa yang bisa saya sebutkan di atas kepala saya:

C ++ memiliki sistem tipe pemikiran yang lebih baik.
Ada beberapa masalah dengan sistem tipe dalam D saat ini, yang tampaknya merupakan kekeliruan dalam desain. Sebagai contoh, saat ini tidak mungkin untuk menyalin const struct ke non-const struct jika struct berisi referensi objek kelas atau pointer karena transitivity dari const dan cara postblit konstruktor bekerja pada tipe nilai. Andrei mengatakan dia tahu bagaimana menyelesaikan ini, tetapi tidak memberikan rincian. Masalahnya tentu bisa diperbaiki (memperkenalkan C ++ - style copy constructors akan menjadi satu perbaikan), tetapi ini adalah masalah utama dalam bahasa saat ini.

Masalah lain yang telah mengganggu saya adalah kurangnya const logis (yaitu tidak mutableseperti di C ++). Ini bagus untuk menulis kode thread-safe, tetapi menyulitkan (mustahil?) Untuk melakukan intialisation lazy dalam objek const (pikirkan fungsi const 'get' yang membangun dan menyimpan nilai yang dikembalikan pada panggilan pertama).

Akhirnya, mengingat masalah-masalah yang ada, aku khawatir tentang bagaimana sisa sistem tipe ( pure, shared, dll) akan berinteraksi dengan segala sesuatu yang lain dalam bahasa setelah mereka dihukum digunakan. Pustaka standar (Phobos) saat ini sangat sedikit menggunakan sistem tipe D yang canggih, jadi saya pikir masuk akal pertanyaan apakah itu akan bertahan di bawah tekanan. Saya skeptis, tetapi optimis.

Perhatikan bahwa C ++ memiliki beberapa jenis kutil sistem (mis. Konstanta non-transitif, membutuhkan iteratordan juga const_iterator) yang membuatnya cukup jelek, tetapi sementara sistem tipe C ++ sedikit salah pada bagian-bagiannya, ia tidak menghentikan Anda menyelesaikan pekerjaan seperti D's terkadang demikian.

Sunting: Untuk memperjelas, saya percaya bahwa C ++ memiliki sistem tipe pemikiran yang lebih baik - belum tentu yang lebih baik - jika itu masuk akal. Pada dasarnya, di DI merasa bahwa ada risiko yang terlibat dalam menggunakan semua aspek dari sistem tipenya yang tidak ada dalam C ++.

D kadang-kadang sedikit terlalu nyaman.
Satu kritik yang sering Anda dengar tentang C ++ adalah bahwa ia menyembunyikan beberapa masalah tingkat rendah dari Anda, mis. Penugasan sederhana seperti a = b;dapat melakukan banyak hal seperti memanggil operator konversi, memanggil operator penugasan yang berlebihan dll, yang dapat berupa sulit dilihat dari kodenya. Beberapa orang seperti ini, beberapa orang tidak. Either way, di D itu lebih buruk (lebih baik?) Karena hal-hal seperti opDispatch, @property, opApply, lazyyang memiliki potensi untuk mengubah kode melihat tidak bersalah dalam hal-hal yang tidak Anda harapkan.

Saya tidak berpikir ini adalah masalah besar secara pribadi, tetapi beberapa mungkin menemukan ini mengesampingkan.

D memerlukan pengumpulan sampah.
Ini dapat dilihat sebagai kontroversial karena dimungkinkan untuk menjalankan D tanpa GC. Namun, hanya karena itu mungkin bukan berarti itu praktis. Tanpa GC, Anda kehilangan banyak fitur D, dan menggunakan perpustakaan standar akan seperti berjalan di ladang ranjau (siapa yang tahu fungsi mana yang mengalokasikan memori?). Secara pribadi, saya pikir itu benar-benar tidak praktis untuk menggunakan D tanpa GC, dan jika Anda bukan penggemar GCs (seperti saya) maka ini bisa sangat mengecewakan.

Definisi array naif dalam D mengalokasikan memori
Ini adalah hewan peliharaan kesayangan saya:

int[3] a = [1, 2, 3]; // in D, this allocates then copies
int a[3] = {1, 2, 3}; // in C++, this doesn't allocate

Tampaknya, untuk menghindari alokasi dalam D, Anda harus melakukan:

static const int[3] staticA = [1, 2, 3]; // in data segment
int[3] a = staticA; // non-allocating copy

Alokasi 'di belakang Anda' kecil ini adalah contoh yang baik dari dua poin saya sebelumnya.

Sunting: Perhatikan bahwa ini adalah masalah yang diketahui sedang dikerjakan.
Sunting: Ini sekarang sudah diperbaiki. Tidak ada alokasi yang dilakukan.

Kesimpulan
Saya telah memfokuskan pada hal negatif dari D vs C ++ karena itulah pertanyaan yang diajukan, tetapi tolong jangan melihat posting ini sebagai pernyataan bahwa C ++ lebih baik dari D. Saya dapat dengan mudah membuat posisi tempat yang lebih besar di mana D lebih baik dari pada C ++. Terserah Anda untuk membuat keputusan mana yang akan digunakan.

Peter Alexander
sumber
Saya melihat D beberapa tahun yang lalu (sebelum 2.0). Pengumpulan sampah tidak benar-benar diperlukan saat itu - ada di sana secara default, tetapi Anda dapat memilih keluar untuk kode tingkat rendah. Hal yang saya pikir salah tentang ini adalah bahwa saya tidak dapat menemukan cara untuk memilih kembali. Misalnya, dalam wadah berbasis pohon, kode perpustakaan dapat mengatur memori untuk simpul pohon itu sendiri. Pohon secara keseluruhan masih bisa dikoleksi, dengan IIRC destruktor yang mengumpulkan semua node tersebut. Tetapi objek yang dirujuk oleh data dalam wadah itu harus dapat dikumpulkan juga - harus ada kait untuk menandai semua item data dalam pohon untuk GC.
Steve314
3
Anda masih dapat menonaktifkan GC untuk kode tingkat rendah - Peter mengatakan bahwa bahasa saat ini sangat tergantung padanya. Selain itu, Anda dapat memberi tahu GC untuk memindai rentang di luar tumpukan yang dikelola menggunakan API: GC.addRange dari core.memory .
Vladimir Panteleev
+1 untuk menunjukkan bahwa pustaka D standar adalah sampah yang dikumpulkan dan kode GC-off bukan interop mulus. Ini bukan sesuatu yang saya pikirkan, tetapi sepertinya itu adalah rintangan besar untuk diatasi.
masonk
132

Ketika saya bergabung dengan pengembangan D, saya berada dalam posisi yang aneh untuk menjadi salah satu orang yang paling tahu tentang C ++. Sekarang saya berada dalam posisi yang bahkan lebih aneh untuk menjadi salah satu dari orang-orang yang paling tahu tentang D. Saya tidak mengatakan ini untuk kredit yang sesuai atau hak-hak menyombongkan diri dengan mengatakan saya berada dalam rasa ingin tahu posisi yang diuntungkan untuk menjawab pertanyaan ini. Hal yang sama berlaku untuk Walter.

Pada umumnya, menanyakan apa yang dilakukan C ++ (dan maksud saya C ++ 2011) lebih baik daripada D sama kontradiktifnya dengan pertanyaan, "Jika Anda membayar seorang profesional untuk membersihkan rumah Anda, tempat apa yang akan mereka tinggalkan lebih kotor dari sebelumnya? " Apa pun nilainya bahwa C ++ dapat melakukan itu D tidak bisa, itu selalu berdiri seperti jempol sakit bagi saya dan Walter, jadi hampir secara definisi tidak ada yang bisa dilakukan C ++ yang tidak dalam jangkauan D.

Satu hal yang jarang dipahami dalam desain bahasa (karena sedikit orang yang beruntung untuk benar-benar melakukan beberapa) adalah bahwa ada kesalahan unforced jauh lebih sedikit daripada yang mungkin muncul. Banyak dari kita pengguna bahasa melihat beberapa konstruk dan yang lain dan berkata, "Eh! Ini sangat salah! Apa yang mereka pikirkan?" Faktanya adalah bahwa contoh paling canggung dalam suatu bahasa adalah setelah beberapa keputusan mendasar yang semuanya sehat dan diinginkan tetapi secara fundamental saling bersaing atau bertentangan satu sama lain (misalnya modularitas dan efisiensi, kesederhanaan dan kontrol dll).

Dengan semua ini dalam pikiran, saya akan menyebutkan beberapa hal yang dapat saya pikirkan, dan untuk masing-masing saya akan menjelaskan bagaimana pilihan D berasal dari keinginan untuk memenuhi piagam lain yang lebih tinggi.

  1. D menganggap semua objek dapat dipindahkan dengan menyalin bitwise. Ini meninggalkan sebagian kecil desain ke C ++, khususnya yang menggunakan pointer internal, yaitu kelas yang mengandung pointer di dalamnya. (Setiap desain seperti itu dapat diterjemahkan tanpa atau dengan biaya efisiensi yang dapat diabaikan ke dalam D, tetapi akan ada upaya penerjemahan yang terlibat.) Kami membuat keputusan ini untuk sangat menyederhanakan bahasa, membuat penyalinan objek lebih efisien tanpa intervensi pengguna atau minimal, dan menghindari seluruh salinan konstruksi moril dan fitur referensi nilai sama sekali.

  2. D melarang jenis-jenis ambigu-jender (yang tidak dapat memutuskan apakah itu tipe nilai atau tipe referensi). Desain seperti itu dengan suara bulat dijauhi dalam C ++ dan hampir selalu salah, tetapi beberapa dari mereka secara teknis benar. Kami membuat pilihan ini karena sebagian besar melarang kode yang salah dan hanya sebagian kecil kode yang benar yang dapat dirancang ulang. Kami percaya ini adalah tradeoff yang bagus.

  3. D melarang hierarki multi-root. Poster sebelumnya di sini menjadi sangat bersemangat tentang topik khusus ini, tetapi ini adalah landasan yang sudah dilalui dengan baik dan tidak ada keuntungan nyata dari hierarki tanpa akar dibandingkan hierarki yang semuanya memiliki akar yang sama.

  4. Dalam D Anda tidak bisa melempar misalnya int. Anda harus melempar objek yang mewarisi Throwable. Tidak ada kontes keadaan yang lebih baik di D, tapi, well, itu satu hal C ++ bisa melakukan itu D tidak bisa.

  5. Dalam C ++ unit enkapsulasi adalah kelas. Dalam D itu adalah modul (yaitu file). Walter membuat keputusan ini karena dua alasan: untuk secara alami memetakan enkapsulasi ke semantik perlindungan sistem, dan untuk meniadakan kebutuhan akan "teman". Pilihan ini terintegrasi sangat baik dalam desain modularitas keseluruhan D. Dimungkinkan untuk mengubah sesuatu menjadi lebih seperti C ++, tetapi itu akan memaksa hal-hal; Pilihan lingkup enkapsulasi C ++ hanya baik untuk desain fisik C ++.

Mungkin ada satu atau dua hal yang lebih kecil, tetapi secara keseluruhan ini seharusnya.

Andrei Alexandrescu
sumber
6
@DeadMG: Agar dapat bekerja di C ++, objek yang dipindahkan akan membutuhkan pointer kembali ke objek yang menunjuk ke sana (sehingga dapat diperbarui selama konstruksi penyalinan). Jika itu masalahnya, dalam D Anda dapat menggunakan konstruktor postblit untuk memperbarui pointer. Tolong jangan berdebat melawan D jika Anda hanya memiliki pengetahuan yang lewat itu.
Peter Alexander
13
@ Peter: Ini harus menjadi referensi meskipun itu seumur hidup hanya berbasis ruang lingkup? Saya harus membuang overhead untuk mengalokasikannya secara dinamis dan tipuan serta cache dan overhead koleksi karena saya ingin alias itu? Juga, saya berharap bahwa kolektor dapat mengumpulkannya secara deterministik, untuk semantik yang setara. Jelas sekali tidak berada dalam kendali.
DeadMG
3
@sbi: Keberadaan kelas atas tidak memengaruhi pilihan Anda sama sekali. Di kisi jenis kelas, selalu ada bagian atas dan bawah. Bagian bawah hanya eksplisit dalam beberapa bahasa . Bagian atas (yaitu Objek dll.) Eksplisit dalam lebih banyak bahasa. Tipe-tipe ini selalu ada dalam konsep; ketika mereka juga dapat diakses, mereka hanya menawarkan beberapa fasilitas tambahan untuk pengguna bahasa tanpa membuat masalah.
Andrei Alexandrescu
6
@quant_dev: Anda akan senang mendengar ada proyek GSoC yang sudah dalam kondisi bagus berfokus pada aljabar linear kinerja tinggi menggunakan BLAS. Ini juga menyediakan implementasi "naif" dari primitif yang sesuai untuk tujuan pengujian dan pembandingan. Untuk menjawab pertanyaan kedua Anda, Java menetapkan bilah cukup rendah untuk membandingkan perpustakaan numerik. Akan selalu mengalami kesulitan untuk melewati penghalang JNI untuk mengakses lib aljabar berkinerja tinggi, dan sintaksisnya akan buruk karena Java tidak memiliki kelebihan operator.
Andrei Alexandrescu
4
@PeterAlexander: DeadMG tepat sasaran. "Anda tidak boleh menggunakan pointer ke tipe nilai" jelas tidak mengetahui fakta bahwa pointer dalam bahasa apa pun umumnya digunakan dengan tipe nilai (apakah Anda benar-benar berharap melihat yang Object*banyak digunakan sebagai int*?) Dan D tampaknya sepenuhnya mengabaikan penalti kinerja, atau mengklaimnya tidak ada. Itu jelas salah - cache miss cukup terlihat dalam banyak kasus, jadi C ++ akan selalu memiliki keunggulan fleksibilitas lebih dari D.
Mehrdad
65

Saya pikir Anda akan kesulitan menemukan banyak D yang objektiflebih buruk dari C ++. Sebagian besar masalah dengan D di mana Anda bisa secara objektif mengatakan itu lebih buruk adalah kualitas masalah implementasi (yang umumnya disebabkan oleh seberapa muda bahasa dan implementasi dan telah diperbaiki pada kecepatan sangat tinggi akhir-akhir ini), atau mereka masalah dengan kekurangan perpustakaan pihak ke-3 (yang akan datang seiring waktu). Bahasa itu sendiri umumnya lebih baik daripada C ++, dan kasus-kasus di mana C ++, sebagai bahasa, lebih baik umumnya akan menjadi tempat ada tradeoff di mana C ++ pergi ke satu arah dan D pergi ke arah lain, atau di mana seseorang memiliki alasan subjektif mengapa mereka berpikir bahwa yang satu lebih baik dari yang lain. Tetapi jumlah alasan obyektif langsung mengapa C ++, sebagai bahasa, lebih baik cenderung sedikit dan jarang.

Sebenarnya, saya harus benar-benar merusak otak saya untuk mencari alasan mengapa C ++, sebagai bahasa, lebih baik daripada D. Apa yang biasanya terlintas dalam pikiran adalah masalah pertukaran.

  1. Karena konstanta D adalah transitif, dan karena bahasanya memiliki kekal , ia memiliki jaminan yang jauh lebih kuat daripada C ++ const, yang berarti bahwa D tidak dan tidak dapat dimiliki mutable. Tidak dapat memiliki const logis . Jadi, Anda mendapatkan keuntungan besar dengan sistem const D, tetapi dalam beberapa situasi, Anda tidak bisa menggunakan constseperti yang Anda miliki di C ++.

  2. D hanya memiliki satu operator cast, sedangkan C ++ memiliki 4 (5 jika Anda menghitung operator cast C). Hal ini membuat berurusan dengan pemain di D lebih mudah dalam kasus umum, tetapi bermasalah ketika Anda benar - benar menginginkan komplikasi / manfaat tambahan yang const_castdisediakan oleh saudara-saudaranya. Tapi D sebenarnya cukup kuat sehingga Anda bisa menggunakan templat untuk mengimplementasikan gips C ++, jadi jika Anda benar-benar menginginkannya, Anda dapat memilikinya (dan mereka bahkan mungkin berakhir di pustaka standar D di beberapa titik).

  3. D memiliki jauh lebih sedikit gips implisit daripada C ++ dan jauh lebih mungkin untuk menyatakan bahwa dua fungsi bertentangan satu sama lain (memaksa Anda untuk lebih spesifik tentang fungsi yang Anda maksud - baik dengan gips atau dengan memberikan jalur modul lengkap ). Kadang-kadang, itu bisa mengganggu, tetapi mencegah semua jenis masalah pembajakan fungsi . Anda tahu bahwa Anda benar-benar memanggil fungsi yang Anda maksudkan.

  4. Sistem modul D jauh lebih bersih daripada C ++'s #includes (belum lagi, cara kompilasi yang lebih cepat), tetapi tidak memiliki jenis penamaan apa pun di luar modul itu sendiri. Jadi, jika Anda ingin namespace dalam sebuah modul, Anda harus pergi dengan rute Java dan menggunakan fungsi statis pada kelas atau struct. Ini berfungsi, tetapi jika Anda benar-benar ingin namespacing, itu jelas tidak sebersih namespace nyata. Namun, untuk sebagian besar situasi, penempatan nama yang disediakan oleh modul itu sendiri sangat banyak (dan sebenarnya cukup canggih dalam hal-hal seperti konflik sebenarnya).

  5. Seperti Java dan C #, D memiliki pewarisan tunggal daripada pewarisan berganda, tetapi tidak seperti Java dan C #, D memberi Anda beberapa cara fantastis untuk mendapatkan efek yang sama tanpa semua masalah yang dimiliki pewarisan berganda C ++ (dan pewarisan berganda C ++ dapat menjadi sangat berantakan) kadang-kadang). D tidak hanya memiliki antarmuka , tetapi juga memiliki string mixin , template mixin , dan alias ini . Jadi, hasil akhirnya bisa dikatakan lebih kuat dan tidak memiliki semua masalah yang dimiliki oleh beberapa warisan C ++.

  6. Mirip dengan C #, D memisahkan struct dan kelas . Kelas adalah tipe referensi yang memiliki pewarisan dan diturunkan Object, sedangkan struct adalah tipe nilai tanpa pewarisan. Pemisahan ini bisa baik dan buruk. Ini menghilangkan masalah slicing klasik dalam C ++ dan membantu tipe terpisah yang benar-benar tipe nilai dari yang seharusnya polimorfik, tetapi pada awalnya, setidaknya, perbedaannya mungkin mengganggu bagi programmer C ++. Pada akhirnya, ada sejumlah manfaat untuk itu, tetapi itu memang memaksa Anda untuk berurusan dengan tipe Anda agak berbeda.

  7. Anggota fungsi dari kelas yang polimorfik secara default. Anda tidak dapat mendeklarasikannya non-virtual . Terserah kompiler untuk memutuskan apakah mereka bisa (yang benar-benar hanya kasus jika mereka final dan tidak mengesampingkan fungsi dari kelas dasar). Jadi, itu bisa menjadi masalah kinerja dalam beberapa kasus. Namun, jika Anda benar-benar tidak memerlukan polimorfisme, maka yang harus Anda lakukan adalah menggunakan struct , dan itu bukan masalah.

  8. D memiliki pengumpul sampah bawaan . Banyak dari C ++ akan menganggap itu sebagai kerugian serius, dan kebenarannya, saat ini, implementasinya dapat menggunakan beberapa pekerjaan serius. Sudah membaik, tapi jelas tidak sebanding dengan pengumpul sampah Jawa. Namun, ini dimitigasi oleh dua faktor. Pertama, jika Anda terutama menggunakan struct dan tipe data lain di stack, maka itu bukan masalah besar. Jika program Anda tidak terus mengalokasikan dan menghapuskan hal-hal di heap, itu akan baik-baik saja. Dan dua, Anda dapat melewati pengumpul sampah jika Anda mau dan cukup menggunakan C's mallocdan free. Ada beberapa fitur bahasa (seperti irisan array) yang harus Anda hindari atau berhati-hati, dan beberapa pustaka standar tidak benar-benar dapat digunakan tanpa setidaknya beberapa penggunaan GC (terutama pemrosesan string), tetapi Anda dapat menulis dalam D tanpa menggunakan pengumpul sampah jika kamu benar-benar ingin. Hal yang cerdas untuk dilakukan adalah mungkin menggunakannya secara umum dan kemudian menghindarinya ketika profil menunjukkan bahwa itu menyebabkan masalah untuk kode kinerja kritis, tetapi Anda dapat menghindarinya sepenuhnya jika Anda mau. Dan kualitas implementasi GC akan meningkat dari waktu ke waktu, menghilangkan banyak kekhawatiran yang mungkin menyebabkan penggunaan GC . Jadi, pada akhirnya, GC tidak akan menjadi masalah besar, dan tidak seperti Java, Anda dapat menghindarinya jika Anda mau.

Mungkin ada yang lain juga, tapi itulah yang bisa saya pikirkan saat ini. Dan jika Anda akan melihat, mereka semua adalah pengorbanan. D memilih untuk melakukan beberapa hal secara berbeda dari C ++ yang memiliki keunggulan pasti atas bagaimana C ++ melakukannya tetapi juga memiliki beberapa kelemahan. Yang lebih baik tergantung pada apa yang Anda lakukan, dan dalam banyak kasus mungkin hanya akan tampak lebih buruk pada awalnya dan kemudian Anda tidak akan memiliki masalah dengan itu setelah Anda terbiasa. Jika ada, masalah dalam D umumnya akan menjadi masalah baru yang disebabkan oleh hal-hal baru yang belum dilakukan bahasa lain sebelumnya atau belum dilakukan dengan cara yang sama seperti yang dimiliki D. Secara keseluruhan, D telah belajar dengan baik dari kesalahan C ++.

Dan D, sebagai bahasa, meningkat lebih dari C ++ dalam banyak hal yang saya pikir umumnya D lebih baik secara objektif.

  1. D memiliki kompilasi bersyarat . Ini adalah salah satu fitur yang sering saya lewatkan ketika saya pemrograman di C ++. Jika C ++ akan menambahkannya, maka C ++ akan meningkat dengan pesat ketika datang ke hal-hal seperti template.

  2. D memiliki refleksi waktu kompilasi .

  3. Variabel adalah thread-local secara default tetapi bisa sharedjika Anda menginginkannya. Ini membuat berurusan dengan utas jauh lebih bersih daripada di C ++. Anda memegang kendali penuh. Anda dapat menggunakan immutabledan menyampaikan pesan untuk berkomunikasi antara utas, atau Anda dapat membuat variabel shareddan melakukannya dengan cara C ++ dengan mutex dan variabel kondisi. Bahkan itu ditingkatkan dari C ++ dengan pengenalan yang disinkronkan (mirip dengan C # dan Java). Jadi, situasi threading D jauh lebih baik daripada C ++.

  4. Template D jauh lebih kuat daripada template C ++, memungkinkan Anda untuk melakukan jauh lebih banyak, jauh lebih mudah. Dan dengan penambahan batasan template, pesan kesalahan jauh lebih baik daripada di C ++. D membuat templat sangat kuat dan bermanfaat. Bukan kebetulan bahwa penulis Modern C ++ Design adalah salah satu kolaborator utama D. Saya menemukan template C ++ kurang serius dibandingkan dengan template D, dan itu bisa sangat membuat frustasi saat pemrograman di C ++.

  5. D memiliki pemrograman kontrak bawaan .

  6. D memiliki kerangka uji unit bawaan.

  7. D memiliki dukungan bawaan untuk unicode dengan string(UTF-8), wstring(UTF-16), dan dstring(UTF-32). Itu membuatnya mudah untuk berurusan dengan unicode. Dan jika Anda hanya ingin menggunakan stringdan umumnya tidak khawatir tentang unicode, Anda dapat - meskipun beberapa pemahaman tentang dasar-dasar unicode membantu dengan beberapa fungsi perpustakaan standar.

  8. Overloading operator D jauh lebih baik daripada C ++, memungkinkan Anda untuk menggunakan satu fungsi untuk membebani banyak operator secara bersamaan. Contoh utama dari ini adalah ketika Anda perlu membebani operator aritmatika dasar dan implementasinya sama kecuali untuk operator. Mixin string membuatnya mudah, memungkinkan Anda untuk memiliki satu, definisi fungsi sederhana untuk semuanya.

  9. Array D jauh lebih baik daripada array C ++. Tidak hanya mereka jenis yang tepat dengan panjang, tetapi mereka dapat ditambahkan dan diubah ukurannya. Menggabungkannya mudah. Dan yang terbaik, mereka memiliki irisan . Dan itu adalah anugerah besar untuk pemrosesan array yang efisien. String adalah array karakter dalam D, dan itu bukan masalah (sebenarnya itu hebat!), Karena array D sangat kuat.

Saya bisa terus dan terus. Banyak perbaikan yang diberikan D adalah hal-hal kecil (seperti menggunakan thisuntuk nama konstruktor atau melarang jika pernyataan atau loop body di mana tanda titik koma adalah seluruh tubuh mereka), tetapi beberapa dari mereka cukup besar, dan ketika Anda menambahkan semuanya, itu membuat pengalaman pemrograman yang jauh lebih baik. C ++ 0x memang menambahkan beberapa fitur yang D miliki dimana C ++ tidak ada (mis. autoDan lambdas), tetapi bahkan dengan semua perbaikannya, masih tidak banyak yang secara objektif lebih baik tentang C ++ sebagai bahasa daripada D.

Tidak ada pertanyaan bahwa ada banyak alasan subyektif untuk menyukai satu sama lain, dan ketidakmatangan relatif dari implementasi D dapat menjadi masalah pada waktu (meskipun telah meningkat sangat cepat akhir-akhir ini - terutama karena repositori dipindahkan ke github ) , dan kurangnya perpustakaan pihak ke-3 pasti bisa menjadi masalah (meskipun fakta bahwa D dapat dengan mudah memanggil fungsi C - dan pada tingkat lebih rendah, fungsi C ++ - pasti mengurangi masalah). Tapi itu adalah kualitas masalah implementasi daripada masalah dengan bahasa itu sendiri. Dan ketika kualitas masalah implementasi diperbaiki, akan jauh lebih menyenangkan untuk menggunakan D.

Jadi, saya kira jawaban singkat untuk pertanyaan ini adalah "sangat sedikit." D, sebagai bahasa, umumnya lebih unggul daripada C ++.

Jonathan M Davis
sumber
2
Bahasa pengumpulan sampah menggunakan memori 2-5x lebih banyak daripada non GC langs (menurut pembicaraan Alexandrescu di YT) sehingga pasti masalah jika itu (mem penggunaan) adalah hambatan.
NoSenseEtAl
9

RAII dan susun penggunaan memori

D 2.0 tidak memungkinkan RAII terjadi di stack karena itu menghapus nilai scopekata kunci dalam mengalokasikan instance kelas pada stack.

Anda tidak dapat melakukan pewarisan tipe nilai dalam D, begitu efektif sehingga memaksa Anda untuk melakukan alokasi tumpukan untuk segala bentuk RAII.
Yaitu, kecuali Anda menggunakan emplace, tetapi itu sangat menyakitkan untuk digunakan, karena Anda harus mengalokasikan memori dengan tangan. (Saya belum menemukannya praktis untuk digunakan emplacedalam D.)

Mehrdad
sumber
6

C ++ jauh lebih baik dalam memaksa Anda untuk menjadi verbose. Ini mungkin lebih baik atau lebih buruk di mata Anda, tergantung pada apakah Anda suka inferensi atau kata-kata.

Bandingkan memoisasi run-time di C ++ :

template <typename ReturnType, typename... Args>
function<ReturnType (Args...)> memoize(function<ReturnType (Args...)> func)
{
    map<tuple<Args...>, ReturnType> cache;
    return ([=](Args... args) mutable {
            tuple<Args...> t(args...);
            return cache.find(t) == cache.end()
                ? cache[t] : cache[t] = func(args...);
    });
}

dengan hal yang sama di D:

auto memoize(F)(F func)
{
    alias ParameterTypeTuple!F Args;
    ReturnType!F[Tuple!Args] cache;
    return (Args args)
    {
        auto key = tuple(args);
        return key in cache ? cache[key] : (cache[key] = func(args));
    };
}

Perhatikan, misalnya, verbositas ekstra dengan template <typename ReturnType, typename... Args>versus (F), Args...versus Args, args...versus args, dll.
Untuk lebih baik atau lebih buruk, C ++ lebih bertele-tele.

Tentu saja, Anda juga bisa melakukan ini dalam D:

template memoize(Return, Args...)
{
    Return delegate(Args) memoize(Return delegate(Args) func)
    {
        Return[Tuple!Args] cache;
        return delegate(Args args)
        {
            auto key = tuple(args);
            return key in cache ? cache[key] : (cache[key] = func(args));
        };
    }
}

dan mereka akan terlihat hampir sama, tetapi kemudian ini akan membutuhkan delegate, sedangkan aslinya diterima setiap objek callable. (Versi C ++ 0x membutuhkanstd::function objek, jadi bagaimanapun juga, itu lebih verbose dan restriktif dalam inputnya ... yang bisa bagus jika Anda suka verbosity, buruk jika Anda tidak.)

Mehrdad
sumber
2

Saya tidak tahu banyak tentang D, tetapi banyak, banyak programmer C ++ yang saya tahu sangat tidak menyukainya, dan saya pribadi harus setuju - Saya tidak suka tampilan D dan tidak akan mengambil yang lebih dekat.

Untuk memahami mengapa D tidak mendapatkan daya tarik lebih, Anda harus mulai dengan memahami apa yang menarik orang ke C ++. Singkatnya, alasan nomor satu adalah kontrol. Ketika Anda memprogram dalam C ++, maka Anda memiliki kontrol penuh atas program Anda. Ingin mengganti perpustakaan Standar? Kamu bisa. Ingin melakukan cast pointer yang tidak aman? Kamu bisa. Ingin melanggar const-correctness? Kamu bisa. Ingin mengganti pengalokasi memori? Kamu bisa. Ingin menyalin sekitar memori mentah tanpa memperhatikan jenisnya? Jika Anda benar-benar mau. Ingin mewarisi dari banyak implementasi? Ini pemakamanmu. Sial, Anda bahkan bisa mendapatkan perpustakaan pengumpulan sampah, seperti kolektor Boehm. Kemudian Anda memiliki masalah seperti kinerja, yang erat mengikuti kontrol - semakin banyak kontrol yang dimiliki programmer, semakin optimal ia dapat membuat programnya.

Berikut adalah beberapa hal yang saya lihat ketika melakukan sedikit riset dan berbicara kepada beberapa orang yang telah mencobanya:

Jenis hierarki terpadu. Pengguna C ++ jarang menggunakan pewarisan, sebagian besar programmer C ++ lebih suka komposisi, dan tipe hanya boleh dihubungkan melalui pewarisan jika ada alasan yang sangat bagus untuk melakukannya. Konsep Obyek sangat melanggar prinsip ini dengan menghubungkan setiap tipe. Selain itu, itu melanggar salah satu prinsip paling dasar C ++ - Anda hanya menggunakan apa yang Anda inginkan. Tidak diberi pilihan tentang mewarisi dari Object, dan biaya yang menyertainya, sangat kuat terhadap apa C + + berdiri sebagai bahasa dalam hal memberikan kontrol programmer atas programnya.

Saya pernah mendengar tentang masalah dengan fungsi dan delegasi. Rupanya, D memiliki kedua fungsi dan delegasi sebagai tipe fungsi runable-time yang dapat dipanggil, dan keduanya tidak sama tetapi keduanya dapat dipertukarkan atau ... sesuatu? Teman saya punya beberapa masalah dengan mereka. Ini jelas merupakan penurunan versi dari C ++, yang baru saja std::functiondilakukan dan Anda selesai.

Maka Anda punya kompatibilitas. D tidak terlalu kompatibel dengan C ++. Maksud saya, tidak ada bahasa yang kompatibel dengan C ++, mari kita hadapi itu, kecuali C ++ / CLI yang agak curang, tetapi sebagai penghalang untuk masuk, harus disebutkan.

Lalu, ada beberapa hal lainnya. Misalnya, baca saja entri Wikipedia.

import std.metastrings;
pragma(msg, Format!("7! = %s", fact_7));
pragma(msg, Format!("9! = %s", fact_9));

printfadalah salah satu fungsi paling tidak aman yang pernah dibuat, dalam keluarga yang sama dengan masalah besar seperti getsdari perpustakaan C Standard lama. Jika Anda mencarinya di Stack Overflow, Anda akan menemukan banyak, banyak pertanyaan yang berkaitan dengan penyalahgunaannya. Pada dasarnya, printfini adalah pelanggaran KERING- Anda memberikan tipe dalam string format, dan kemudian memberikannya lagi saat Anda memberikan argumen. Pelanggaran KERING di mana jika Anda salah, maka hal-hal yang sangat buruk terjadi- katakanlah, jika Anda mengubah typedef dari bilangan bulat 16-bit menjadi 32-bit. Ini juga tidak dapat diperpanjang sama sekali- bayangkan apa yang akan terjadi jika semua orang menemukan penentu format mereka sendiri. Iostreams C ++ mungkin lambat, dan pilihan operator mereka mungkin bukan yang terbesar, dan antarmuka mereka bisa menggunakan pekerjaan, tetapi mereka pada dasarnya dijamin aman, dan KERING tidak dilanggar, dan mereka dapat dengan mudah diperpanjang. Ini bukan sesuatu yang bisa dikatakan printf.

Tidak ada pewarisan berganda. Itu sangat bukan cara C ++. Pemrogram C ++ berharap memiliki kendali penuh atas program mereka dan bahasa yang menegakkan apa yang tidak dapat Anda warisi merupakan pelanggaran terhadap prinsip itu. Selain itu, itu membuat warisan (bahkan lebih) rapuh, karena jika Anda mengubah jenis dari antarmuka ke kelas karena Anda ingin memberikan implementasi default atau sesuatu, tiba-tiba semua kode pengguna Anda rusak. Itu bukan hal yang baik.

Contoh lain adalah stringdan wstring. Dalam C ++ sudah cukup menyakitkan untuk harus mengkonversi di antara mereka, dan apakah pustaka ini mendukung Unicode, dan pustaka C lama ini hanya menggunakan const char*, dan harus menulis versi berbeda dari fungsi yang sama tergantung pada tipe argumen string yang Anda inginkan. Khususnya, tajuk Windows, misalnya, memiliki beberapa makro yang sangat menjengkelkan untuk mengatasi masalah yang sering dapat mengganggu kode Anda sendiri. Menambahkan dstringke campuran hanya akan membuat segalanya lebih buruk, karena sekarang alih-alih dua jenis string, Anda harus mengelola tiga. Memiliki lebih dari satu tipe string akan meningkatkan rasa sakit pemeliharaan dan memperkenalkan kode berulang yang berurusan dengan string.

Scott Meyers menulis:

D adalah bahasa pemrograman yang dibangun untuk membantu programmer mengatasi tantangan pengembangan perangkat lunak modern. Ia melakukannya dengan membina modul yang saling terhubung melalui antarmuka yang tepat, federasi paradigma pemrograman yang terintegrasi erat, isolasi thread yang diberlakukan bahasa, keselamatan tipe modular, model memori yang efisien, dan banyak lagi.

Isolasi thread yang didukung bahasa bukan merupakan nilai tambah. Pemrogram C ++ mengharapkan kontrol penuh atas program mereka, dan bahasa yang memaksa sesuatu jelas bukan yang diperintahkan dokter.

Saya juga akan menyebutkan manipulasi string waktu kompilasi. D memiliki kemampuan untuk menafsirkan kode D pada waktu kompilasi. Ini bukan nilai tambah. Pertimbangkan sakit kepala masif yang disebabkan oleh preprosesor C yang relatif terbatas, yang terkenal oleh semua programmer veteran C ++, dan kemudian bayangkan betapa buruknya fitur ini akan disalahgunakan. Kemampuan untuk membuat kode D pada waktu kompilasi sangat bagus, tetapi harus semantik , bukan sintaksis.

Selain itu, Anda dapat mengharapkan refleks tertentu. D memiliki koleksi sampah, yang akan diasosiasikan oleh para programmer C ++ dengan bahasa-bahasa seperti Java dan C # yang secara langsung menentangnya dalam filosofi, dan persamaan sintaksis juga akan mengingatkan mereka. Ini belum tentu dibenarkan secara objektif, tetapi itu adalah sesuatu yang tentu harus dicatat.

Pada dasarnya, ia tidak menawarkan banyak yang tidak bisa dilakukan oleh programmer C ++. Mungkin lebih mudah untuk menulis metaprogram faktorial dalam D, tetapi kita sudah dapat menulis metaprogram faktorial dalam C ++. Mungkin dalam D Anda dapat menulis pelacak ray waktu kompilasi, tetapi tidak ada yang benar-benar ingin melakukannya. Dibandingkan dengan pelanggaran mendasar filsafat C ++, apa yang dapat Anda lakukan dalam D tidak terlalu menonjol.

Bahkan jika hal-hal ini hanya masalah di permukaan, maka saya cukup yakin bahwa fakta bahwa di permukaan, D sebenarnya tidak terlihat seperti C ++ sama sekali mungkin merupakan alasan yang baik bahwa banyak programmer C ++ tidak bermigrasi ke D. Mungkin D perlu melakukan iklan pekerjaan yang lebih baik.

DeadMG
sumber
9
@DeadMG: Ini 100% salah dan tidak ada gunanya mengatakan Ini jelas merupakan penurunan versi dari C ++, yang baru saja std::functiondilakukan dan Anda selesai. Mengapa? Karena Anda juga, misalnya, memiliki pointer fungsi. Ini persis hal yang sama di "fungsi" D: D adalah pointer fungsi, dan "delegasi" D sama dengan C ++ std::function(kecuali bahwa mereka built-in). Tidak ada "downgrade" di mana pun - dan ada korespondensi 1: 1 di antara mereka, jadi sama sekali tidak membingungkan jika Anda terbiasa dengan C ++.
Mehrdad
10
@ Mark Trapp: Saya harus mengakui bahwa saya tidak mengerti pendirian Anda tentang topik - komentar tidak boleh digunakan untuk, Anda tahu, mengomentari jawaban?
klickverbot
6
@ Mark Trapp: Maksud saya adalah bahwa sebagian besar komentar di sini tidak usang (diskusi meta yang Anda tautkan secara khusus berlaku untuk saran yang telah dimasukkan ke dalam pos asli), tetapi menunjukkan ketidakakuratan faktual dalam pos, yang masih ada .
klickverbot
7
Catatan tentang format: Fungsi format D adalah typesafe (memecahkan masalah keselamatan / limpahan) dan tidak melanggar KERING karena string format hanya menentukan bagaimana argumen harus diformat, bukan tipenya. Ini dimungkinkan berkat variadics huruf D yang aman. Karenanya, keberatan itu setidaknya tidak sepenuhnya benar.
Justin W
17
@ Mark: Apa pun kebijakan saat ini mengenai mereka, saya merasa bodoh dan menghambat bahwa diskusi komentar dihapus . Saya pikir jawaban ini memiliki diskusi yang luas (yang saya sekarang tertarik), tetapi saya tidak yakin, dan saya tidak punya cara untuk mengetahuinya. Ruangan yang Anda tautkan memiliki lebih dari 10 ribu pesan, dan saya tidak memiliki kesempatan sama sekali untuk menemukan diskusi yang saya ingat pernah terjadi, tetapi tidak dapat mengingat isinya. Diskusi mengenai jawaban ini ada di sini, untuk jawaban ini , dan bukan ke ruang obrolan, di mana mereka mungkin berbaur dalam diskusi tentang seks, narkoba, dan rock'n'roll.
sbi
1

Satu hal yang saya hargai dalam C ++ adalah kemampuan untuk mendokumentasikan argumen fungsi atau mengembalikan nilai sebagai referensi C ++ alih-alih sebuah pointer, karenanya menyiratkan mengambil nullnilai yang tidak bernilai.

Versi D:

class A { int i; }

int foo(A a) {
    return a.i; // Will crash if a is null
}

int main() {
    A bar = null;
    // Do something, forgetting to set bar in all
    // branches until finally ending up at:
    return foo(bar);
}

Versi C ++:

class A { int i; };

int foo(A& a) {
    return a.i; // Will probably not crash since
                // C++ references are less likely
                // to be null.
}

int main() {
    A* bar = null;
    // Do something, forgetting to set bar in all
    // branches until finally ending up at:
    // Hm.. I have to dereference the bar-pointer
    // here, otherwise it wont compile.  Lets add
    // a check for null before.
    if (bar)
        return foo(*bar);
    return 0;
}

Agar adil Anda bisa menjadi sangat dekat dengan C ++ dengan membuat Amenjadi D structdan menandai foo()-argumen sebagai a ref(kelas adalah tipe referensi dan struct adalah tipe nilai dalam D, mirip dengan C #).

Saya percaya ada rencana untuk membuat NonNullabletemplat untuk kelas sebagai konstruksi pustaka standar D sebagai gantinya. Meski begitu saya suka singkatnya hanya Type&dibandingkan dengan NonNullable(Type), dan akan lebih memilih non-nullable sebagai default (rendering sesuatu seperti Typedan Nullable(Type)). Tapi sudah terlambat untuk mengubah itu untuk D dan saya keluar topik sekarang.

lumor
sumber
3
Kedua argumen fungsi dan nilai kembali dalam D dapat ditandai dengan refuntuk memberi Anda efek yang sama dengan C ++ &. Satu perbedaan utama adalah bahwa hal refitu tidak akan berlangsung sementara meskipun itu const.
Jonathan M Davis
Saya suka cara mengembalikan referensi ke variabel lokal dilarang di D, saya tidak menyadarinya sampai saya membaca komentar Anda. Tetapi Anda masih dapat mengembalikan referensi nol non-lokal tanpa memikirkannya dengan cara di mana operator C dereference akan membuat Anda berpikir.
lumor
Anda hal-hal yang membingungkan. Kelas selalu referensi, dan itu terpisah dari ref. Referensi dalam D seperti referensi di Jawa. Mereka adalah pointer yang dikelola. Melewati atau kembali dengan ref sama seperti melewati atau kembali dengan & di C ++. Melewati referensi kelas dengan ref sama seperti melewatkan pointer di C ++ dengan & (misalnya A * &). Kelas tidak masuk stack. Ya, NonNullable akan memungkinkan untuk memiliki referensi kelas yang dijamin non-null, tetapi itu benar-benar terpisah dari referensi. Apa yang Anda coba lakukan dalam kode C ++ tidak bekerja di D karena kelas tidak masuk stack. Struktur melakukannya.
Jonathan M Davis
1
Jadi ya, bisa memiliki referensi kelas yang bukan-nullabe akan lebih baik, tetapi C ++ berhasil melakukan apa yang Anda tampilkan karena memungkinkan kelas berada di stack dan memungkinkan pointer untuk direferensikan. Dan sementara Anda bisa merujuk pointer dalam D, kelas adalah referensi, bukan pointer, sehingga Anda tidak bisa referensi referensi. Karena Anda tidak bisa meletakkannya di tumpukan, dan Anda tidak bisa men-dereferensi mereka, tidak ada cara yang dibangun ke D untuk memiliki kelas yang tidak bisa nol. Ini adalah kerugian, tetapi NonNullable akan memperbaikinya, dan keuntungan dari pemisahan struct dan kelas umumnya lebih besar pula.
Jonathan M Davis
2
Referensi C ++ tidak boleh nol oleh standar bahasa (mengatakan "mungkin tidak akan nol" tidak benar karena tidak bisa nol). Saya berharap ada cara untuk melarang null sebagai nilai yang valid untuk suatu kelas.
jsternberg
1

Hal yang paling penting bahwa C ++ "lebih baik" daripada D adalah berinteraksi dengan perpustakaan lama . Berbagai mesin 3D, OpenCL dan sejenisnya. Karena D adalah baru, ia memiliki jumlah perpustakaan berbeda yang jauh lebih kecil untuk dipilih.

Perbedaan penting lainnya antara C ++ dan D adalah bahwa C ++ memiliki banyak vendor independen secara finansial, tetapi pada 2014 D secara praktis hanya memiliki satu , tim 2 orang yang menciptakannya. Sangat menarik bahwa "prinsip sumber kedua" yang mengatakan bahwa proyek tidak boleh bergantung pada teknologi, komponen, yang hanya memiliki satu, tunggal, vendor, tampaknya berlaku bahkan untuk perangkat lunak.

Sebagai perbandingan, versi pertama dari interpreter Ruby ditulis oleh penemu Ruby, Yukihiro Matsumoto, tetapi juru bahasa Ruby mainstream era 2014 telah ditulis secara praktis dari awal oleh orang lain. Oleh karena itu, Ruby dapat dilihat sebagai bahasa yang memiliki lebih dari satu vendor yang mandiri secara finansial. D, di sisi lain, bisa menjadi teknologi yang luar biasa, tetapi itu tergantung pada beberapa pengembang yang mengembangkannya.

Sejarah Jawa menunjukkan bahwa bahkan jika suatu teknologi, dalam hal ini, Jawa, memiliki pemodal yang bagus, tetapi tunggal, ada risiko besar bahwa teknologi tersebut pada dasarnya dibuang, terlepas dari basis pengguna korporat yang besar. Kutipan dari Yayasan Perangkat Lunak Apache , di mana Komisi Eropa mewakili "Komite Eksekutif":

Oracle menyediakan EC dengan permintaan spesifikasi Java SE 7 dan lisensi yang saling bertentangan, sangat membatasi distribusi implementasi independen dari spesifikasi, dan yang paling penting, melarang distribusi implementasi open source independen dari spesifikasi.

Sebagai catatan sejarah, dapat dikatakan bahwa applet Java memiliki perangkat keras yang dipercepat kanvas 3D bertahun-tahun sebelum WebGL HTML5 dikembangkan. Masalah kecepatan awal applet Java dapat dipecahkan, jika Java merupakan proyek komunitas, tetapi eksekutif satu-satunya pemodal Java, Sun Microsystems, tidak merasa cukup penting untuk memperbaiki implementasi Java. Hasil akhirnya: kanvas HTML5 oleh beberapa vendor sebagai "replika orang miskin" dari kerangka kerja Java GUI (Swing, dll.). Yang cukup menarik, di sisi server bahasa pemrograman Python memiliki kelebihan yang sama seperti yang dijanjikan Java: menulis sekali, berjalan di setiap server, terlepas dari perangkat kerasnya, asalkan aplikasi Python tidak dikompilasi ke kode mesin. Python adalah tentang tua / muda seperti Jawa, tetapi tidak seperti Java, itu '

Ringkasan:

Ketika mengevaluasi teknologi untuk penggunaan produksi, sifat paling penting dari teknologi adalah orang-orang, yang mengembangkannya, proses sosial, di mana pengembangan berlangsung, dan jumlah tim pengembangan yang mandiri secara finansial.

Apakah lebih menguntungkan menggunakan teknologi T1 daripada teknologi T2 tergantung pada vendor teknologi dan apakah teknologi T1 memungkinkan untuk menyelesaikan masalah terkait proyek lebih murah daripada T2. Misalnya, jika masalah pemasok tunggal diabaikan, maka untuk sistem informasi Java akan menjadi teknologi "lebih baik" daripada C ++, karena binari Java tidak perlu dikompilasi ulang saat pemasangan perangkat keras baru dan jumlah pekerjaan pengembangan perangkat lunak terkait manajemen memori lebih kecil untuk Java daripada untuk C ++. Proyek yang dikembangkan dari awal, misalnya proyek yang tidak bergantung pada perpustakaan lain, mungkin lebih murah untuk dikembangkan di D daripada C ++, tetapi, di sisi lain, C ++ memiliki lebih dari satu vendor dan karenanya kurang berisiko dalam jangka panjang . (Contoh Java, di mana Sun Microsystems hampir OK,

Solusi yang Mungkin untuk beberapa Keterbatasan C ++

Salah satu solusi yang mungkin untuk beberapa keterbatasan C ++ adalah dengan menggunakan pola desain, di mana tugas awal diambil berkeping-keping dan potongan-potongan itu "diurutkan" (diklasifikasikan, dikelompokkan, dibagi, kata-kata bagus-lain untuk- the-same-thing) ke 2 kelas: mengontrol tugas-tugas terkait logika , di mana pola akses memori tidak memungkinkan lokalitas; tugas seperti pemrosesan sinyal , di mana lokalitas mudah dicapai. Tugas pemrosesan "suka" sinyal dapat diimplementasikan sebagai satu set program konsol yang relatif sederhana. Tugas terkait kontrol logika ditempatkan semua ke satu skrip yang ditulis dalam Ruby atau Python atau yang lainnya, di mana kenyamanan pengembangan perangkat lunak memiliki prioritas lebih tinggi daripada kecepatan.

Untuk menghindari inisialisasi proses sistem operasi yang mahal dan penyalinan data antara proses sistem operasi, rangkaian aplikasi konsol C ++ kecil dapat diimplementasikan sebagai program C ++ tunggal yang di-boot sebagai "servlet" oleh Ruby / Python / etc. naskah. Ruby / Python / etc. script mematikan servlet sebelum keluar. Komunikasi antara "servlet" dan Ruby / Python / etc. skrip berlangsung di atas pipa bernama Linux atau mekanisme serupa.

Jika tugas awal tidak memungkinkan dirinya untuk dengan mudah dibagi menjadi beberapa bagian yang dapat diklasifikasikan ke dalam 2 kelas yang disebutkan di atas, maka hal yang harus dicoba mungkin adalah mengutarakan kembali masalah sehingga tugas awal berubah.

Martin Vahi
sumber