Saya tertarik pada ide C ++ - seperti const
tidak eksekusi tertentu (seperti membuang const
).
Ambil contoh C # - tidak memiliki C ++ - seperti const, dan alasannya adalah biasa - orang dan waktu. Di sini juga tampaknya tim C # melihat eksekusi C ++ dari const
, pemasaran CLR dan sudah cukup pada saat ini (lihat mengapa tidak ada metode anggota const dalam parameter c # dan const ; terima kasih Svick). Jadilah jika kita bergerak lebih jauh dari itu, apakah ada yang lain?
Apakah ada sesuatu yang lebih dalam? Ambil contoh multi-inheritance - biasanya dianggap sulit untuk dipahami (untuk pengguna) dan dengan demikian tidak ditambahkan ke bahasa (seperti masalah intan).
Apakah ada sesuatu di NATURE dari const
yang berpose masalah bahwa lebih baik untuk bahasa untuk menghindarinya? Sesuatu seperti memutuskan apakah const
harus dalam atau dangkal (memiliki const
wadah artinya saya tidak dapat menambahkan elemen baru atau mengubah elemen yang ada juga; bagaimana jika elemen-elemen tersebut dari tipe referensi)?
UPDATE : sementara saya menyebutkan C #, dan dengan demikian membuat perspektif sejarah saya tertarik pada sifat masalah potensial const
ke bahasa.
Ini bukan tantangan bahasa. Harap abaikan faktor-faktor seperti tren atau popularitas saat ini - Saya hanya tertarik pada masalah teknis - terima kasih.
sumber
Jawaban:
Catatan yakin jika ini memenuhi syarat untuk Anda, tetapi dalam bahasa fungsional seperti Standar ML semuanya tidak dapat diubah secara default. Mutasi didukung melalui tipe generik
ref
erence. Jadiint
variabel tidak berubah, danref int
variabel adalah wadah yang bisa berubah untukint
s. Pada dasarnya, variabel adalah variabel nyata dalam arti matematika (nilai yang tidak diketahui tetapi tetap) danref
s adalah "variabel" dalam arti pemrograman imperatif - sel memori yang dapat ditulis dan dibaca. (Saya suka menyebutnya mereka tugas .)Saya pikir masalahnya
const
adalah dua kali lipat. Pertama, C ++ tidak memiliki pengumpulan sampah, yang diperlukan untuk memiliki struktur data persisten non-sepele .const
harus mendalam untuk masuk akal, namun memiliki nilai yang sepenuhnya tidak dapat diubah dalam C ++ tidak praktis.Kedua, di C ++ Anda harus memilih untuk ikut serta
const
daripada menyisih. Tetapi ketika Anda lupaconst
sesuatu dan kemudian memperbaikinya, Anda akan berakhir dalam situasi "keracunan const" yang disebutkan dalam jawaban @ RobY di manaconst
perubahan akan mengalir di seluruh kode. Jikaconst
itu default, Anda tidak akan menemukan diri Anda berlakuconst
surut. Selain itu, harus menambahkan diconst
mana-mana menambahkan banyak suara ke kode.Saya menduga bahasa umum yang mengikuti (misalnya Jawa) sangat dibentuk oleh keberhasilan dan cara berpikir C dan C ++. Contoh kasus, bahkan dengan pengumpulan sampah, sebagian besar API pengumpulan bahasa mengasumsikan struktur data yang bisa berubah. Fakta bahwa semuanya bisa berubah dan ketidakmampuan dilihat sebagai kasus sudut berbicara banyak tentang pola pikir imperatif di balik bahasa populer.
EDIT : Setelah merenungkan komentar greenoldman, saya menyadari bahwa
const
itu tidak secara langsung tentang kekekalan data;const
mengkodekan ke dalam jenis metode apakah itu memiliki efek samping pada instance.Dimungkinkan untuk menggunakan mutasi untuk mencapai perilaku yang transparan secara referensial . Misalkan Anda memiliki fungsi yang ketika dipanggil berturut-turut mengembalikan nilai yang berbeda - misalnya, fungsi yang membaca satu karakter dari
stdin
. Kita dapat menggunakan cache / memoize hasil dari fungsi ini untuk menghasilkan aliran nilai yang secara referensi transparan. Aliran akan menjadi daftar yang ditautkan yang simpulnya akan memanggil fungsi saat pertama kali Anda mencoba mengambil nilainya, tetapi kemudian menyimpan hasilnya. Jadi jikastdin
terkoneksiHello, world!
, pertama kali Anda mencoba mengambil nilai dari simpul pertama, itu akan membaca satuchar
dan kembaliH
. Setelah itu akan terus kembaliH
tanpa panggilan lebih lanjut untuk membaca achar
. Demikian juga, simpul kedua akan membacachar
daristdin
pertama kali Anda mencoba mengambil nilainya, kali ini kembalie
dan menyimpan hasilnya.Hal yang menarik di sini adalah bahwa Anda telah mengubah proses yang secara inheren stateful menjadi objek yang tampaknya tanpa kewarganegaraan. Namun, perlu untuk memutasikan keadaan internal objek (dengan menyimpan hasil) untuk mencapai ini - mutasi adalah efek jinak . Tidak mungkin membuat kami
CharStream
const
meskipun aliran berperilaku seperti nilai yang tidak berubah. Sekarang bayangkan adaStream
antarmuka denganconst
metode, dan semua fungsi Anda harapkanconst Streams
. AndaCharStream
tidak dapat mengimplementasikan antarmuka!( EDIT 2: Rupanya ada kata kunci C ++ yang disebut
mutable
yang akan memungkinkan kita untuk berbuat curang dan membuatCharStream
const
. Namun, celah ini menghancurkanconst
jaminan - sekarang Anda benar-benar tidak dapat memastikan sesuatu tidak akan bermutasi melaluiconst
metodenya. Saya kira itu bukan itu buruk karena Anda harus secara eksplisit meminta celah, tetapi Anda masih sepenuhnya bergantung pada sistem kehormatan.)Kedua, anggaplah Anda memiliki fungsi tingkat tinggi - yaitu, Anda bisa meneruskan fungsi sebagai argumen ke fungsi lain.
const
ness adalah bagian dari tanda tangan suatu fungsi, jadi Anda tidak akan bisa meneruskan nonfungsiconst
sebagai argumen ke fungsi yang mengharapkanconst
fungsi. Menegakkan secara buta diconst
sini akan menyebabkan hilangnya keumuman.Akhirnya, memanipulasi
const
objek tidak menjamin bahwa itu tidak bermutasi beberapa keadaan eksternal (statis atau global) di belakang Anda, jadiconst
jaminan tidak sekuat yang awalnya muncul.Tidak jelas bagi saya bahwa pengkodean ada atau tidaknya efek samping ke dalam sistem tipe secara universal adalah hal yang baik.
sumber
var
sesuai permintaan hanya menyisakan satu masalah - kedalaman?const
referensi ke non-const
objek. Meski begitu, saya tidak percaya itu masuk akal untuk memiliki dangkalconst
. Inti dariconst
adalah jaminan bahwa Anda tidak akan dapat mengubah objek melalui referensi itu. Anda tidak boleh mengelakconst
dengan membuat non-const
referensi, jadi mengapa tidak apa-apa untuk mengelakconst
dengan memutasikan anggota objek?func foo(const String &s)
dan ini adalah sinyal yangs
tidak akan diubahfoo
.null
dan pewarisan.)Masalah utamanya adalah programmer cenderung tidak cukup menggunakannya, jadi ketika mereka menabrak tempat di mana itu diperlukan, atau pengelola kemudian ingin memperbaiki const-correctness, ada efek riak yang besar. Anda masih dapat menulis kode tidak dapat diubah yang sangat baik tanpa
const
, kompiler Anda tidak akan menegakkannya, dan akan lebih sulit untuk mengoptimalkannya. Beberapa orang lebih suka kompiler mereka daripada membantu mereka. Saya tidak mengerti orang-orang itu, tetapi ada banyak dari mereka.Dalam bahasa fungsional, hampir semuanya
const
, dan menjadi bisa berubah adalah pengecualian langka, jika diizinkan sama sekali. Ini memiliki beberapa keuntungan, seperti konkurensi yang lebih mudah dan penalaran yang lebih mudah tentang status bersama, tetapi perlu dibiasakan jika Anda berasal dari bahasa dengan budaya yang bisa berubah. Dengan kata lain, tidak menginginkanconst
adalah masalah orang, bukan masalah teknis.sumber
Saya melihat kekurangannya sebagai:
"keracunan const" adalah masalah ketika satu deklarasi const dapat memaksa deklarasi sebelumnya atau berikut untuk menggunakan const, dan itu dapat menyebabkan yang sebelumnya dari deklarasi berikut untuk menggunakan const, dll. Dan jika keracunan const mengalir ke kelas di perpustakaan bahwa Anda tidak memiliki kendali atas, maka Anda bisa terjebak di tempat yang buruk.
itu bukan jaminan mutlak. Biasanya ada kasus di mana konst hanya melindungi referensi, tetapi tidak dapat melindungi nilai-nilai yang mendasarinya karena satu dan lain alasan. Bahkan dalam C, ada kasus tepi yang tidak bisa dijangkau oleh const, yang melemahkan janji yang diberikan const.
secara umum, sentimen industri tampaknya bergerak menjauh dari jaminan waktu kompilasi yang kuat, betapapun kenyamanan yang mereka dapat berikan kepada Anda dan saya. Jadi untuk sore hari saya habiskan menyentuh 66% basis kode saya karena keracunan const, beberapa Python guy telah menggedor 10 modul Python yang bisa dikerjakan dengan baik, dirancang dengan baik, teruji, berfungsi penuh. Dan dia bahkan tidak meretas ketika dia melakukannya.
Jadi mungkin pertanyaannya adalah, mengapa meneruskan fitur yang berpotensi kontroversial yang bahkan beberapa ahli tidak jelas ketika Anda mencoba untuk mengadopsi bahasa baru Anda yang rumit?
EDIT: jawaban singkat, bahasa baru memiliki bukit yang curam untuk didaki untuk diadopsi. Desainernya benar-benar harus berpikir keras tentang fitur apa yang perlu diadopsi. Ambil Go, misalnya. Google semacam secara brutal memotong beberapa pertempuran agama terdalam dengan membuat beberapa pilihan desain gaya Conan-the-Barbarian, dan saya benar-benar berpikir bahasanya lebih baik untuk itu, dari apa yang saya lihat.
sumber
int *
pointer bisa berubah ke nilai bisa berubah,int const *
pointer bisa berubah ke nilaiint * const
const , pointer ke nilai bisa berubah,int const * const
pointer ke nilai const.const
), jadi "alasan" seperti itu saya anggap tidak relevan (setidaknya untuk pertanyaan ini). Tentangconst
keracunan - dapatkah Anda memberi contoh? Karena AFAIK adalah keuntungannya, Anda melewatkan sesuatuconst
dan itu harus tetapconst
.const
masalah tetapi mengubah tipenya - apa pun yang Anda lakukan, itu akan selalu menjadi masalah. Pertimbangkan untuk lulusRichString
, dan kemudian sadarilah Anda untuk lulus dengan lebih baikString
.const
. Terlalu mudah untuk tidak melakukanconst
hal-hal yang seharusnyaconst
karena Anda harus memilih untuk masuk daripada keluar dari itu.Ada beberapa masalah filosofis dalam menambah
const
bahasa. Jika Anda mendeklarasikanconst
ke kelas, itu berarti bahwa kelas tidak dapat berubah. Tetapi kelas adalah seperangkat variabel yang digabungkan dengan metode (atau mutator). Kami mencapai abstraksi dengan menyembunyikan keadaan kelas di balik serangkaian metode. Jika kelas dirancang untuk menyembunyikan negara, maka Anda perlu mutator untuk mengubah keadaan itu dari luar dan kemudian tidakconst
lagi. Jadi hanya mungkin untuk mendeklarasikanconst
ke kelas yang tidak dapat diubah. Jadiconst
sepertinya hanya mungkin dalam skenario di mana kelas (atau tipe yang ingin Anda nyatakanconst
) sepele ...Jadi, apa kita perlu
const
? Saya rasa tidak. Saya pikir Anda dapat dengan mudah melakukannya tanpaconst
memiliki desain yang bagus. Data apa yang Anda butuhkan dan di mana, metode mana yang merupakan metode data-ke-data dan abstraksi apa yang Anda butuhkan untuk I / O, jaringan, tampilan dll. Kemudian Anda secara alami memecah modul dan kelas muncul yang berhubungan dengan negara dan Anda memiliki metode dan kelas abadi yang tidak membutuhkan status.Saya pikir sebagian besar masalah muncul dengan objek data besar lemak yang dapat menyimpan, mengubah dan menggambar sendiri dan kemudian Anda ingin meneruskannya ke renderer misalnya. Jadi Anda tidak dapat menyalin isi data, karena itu terlalu mahal untuk objek data besar. Tapi Anda juga tidak ingin itu berubah, jadi Anda perlu sesuatu seperti yang
const
Anda pikirkan. Biarkan kompiler mencari tahu kekurangan desain Anda. Namun, jika Anda membagi objek-objek itu hanya menjadi objek data yang tidak dapat diubah dan mengimplementasikan metode dalam modul yang bertanggung jawab, Anda dapat mengedarkan (hanya) pointer dan melakukan hal-hal yang ingin Anda lakukan dengan data sambil juga menjamin kekekalan.Saya tahu bahwa dimungkinkan dalam C ++ untuk mendeklarasikan beberapa metode
const
dan tidak mendeklarasikan pada metode lain, karena mereka adalah mutator. Dan kemudian beberapa waktu kemudian Anda memerlukan cache dan kemudian pengambil mengubah objek (karena malas memuat) dan tidakconst
lagi. Tapi itulah inti dari abstraksi ini, kan? Anda tidak tahu status apa yang akan dimutasi dengan setiap panggilan.sumber
const
(dalam pengertian C ++ ) Anda harus mendefinisikan antarmuka, juga untuk semua properti.