Saya telah membaca pertanyaan terkait Apakah ada pola desain yang tidak perlu dalam bahasa dinamis seperti Python? dan ingat kutipan ini di Wikiquote.org
Hal yang menakjubkan tentang pengetikan dinamis adalah Anda dapat mengekspresikan apa pun yang dapat dikomputasi. Dan sistem tipe jangan - sistem tipe biasanya decidable, dan mereka membatasi Anda untuk subset. Orang-orang yang menyukai sistem tipe statis berkata “tidak apa-apa, itu cukup baik; semua program menarik yang ingin Anda tulis akan berfungsi sebagai tipe ”. Tapi itu konyol - sekali Anda memiliki sistem tipe, Anda bahkan tidak tahu program apa yang menarik.
--- Rekayasa Perangkat Lunak Radio Episode 140: Newspeak dan Jenis Pluggable dengan Gilad Bracha
Saya bertanya-tanya, adakah pola atau strategi desain yang berguna yang, dengan menggunakan rumusan kutipan, "tidak berfungsi sebagai tipe"?
sumber
Jawaban:
Jenis kelas satu
Mengetik dinamis berarti Anda memiliki tipe kelas satu: Anda dapat memeriksa, membuat, dan menyimpan tipe saat runtime, termasuk tipe bahasa itu sendiri. Ini juga berarti bahwa nilai diketik, bukan variabel .
Bahasa yang diketik secara statis dapat menghasilkan kode yang bergantung pada tipe dinamis juga, seperti metode pengiriman, kelas ketik, dll. Tetapi dengan cara yang umumnya tidak terlihat oleh runtime. Paling-paling, mereka memberi Anda beberapa cara untuk melakukan introspeksi. Atau, Anda bisa mensimulasikan tipe sebagai nilai tetapi kemudian Anda memiliki sistem tipe dinamis ad-hoc.
Namun, sistem tipe dinamis jarang hanya memiliki tipe kelas satu. Anda dapat memiliki simbol kelas satu, paket kelas satu, kelas satu .... semuanya. Ini berbeda dengan pemisahan ketat antara bahasa kompiler dan bahasa runtime dalam bahasa yang diketik secara statis. Apa yang dapat dilakukan oleh kompiler atau juru bahasa yang bisa dilakukan runtime juga.
Sekarang, mari kita sepakat bahwa inferensi jenis adalah hal yang baik dan saya ingin kode saya diperiksa sebelum menjalankannya. Namun, saya juga suka bisa menghasilkan dan mengkompilasi kode saat runtime. Dan saya juga suka melakukan precompute pada waktu kompilasi. Dalam bahasa yang diketik secara dinamis, ini dilakukan dengan bahasa yang sama. Di OCaml, Anda memiliki sistem jenis modul / functor, yang berbeda dari sistem jenis utama, yang berbeda dari bahasa preprosesor. Di C ++, Anda memiliki bahasa templat yang tidak ada hubungannya dengan bahasa utama, yang umumnya tidak mengetahui jenis selama eksekusi. Dan itu baik - baik saja dalam bahasa itu, karena mereka tidak ingin memberikan lebih banyak.
Pada akhirnya, itu tidak mengubah benar-benar apa jenis perangkat lunak dapat Anda mengembangkan, tapi ekspresivitas perubahan bagaimana Anda mengembangkan mereka dan apakah sulit atau tidak.
Pola
Pola yang bergantung pada tipe dinamis adalah pola yang melibatkan lingkungan dinamis: kelas terbuka, pengiriman, basis data objek dalam memori, serialisasi, dll. Hal-hal sederhana seperti wadah umum berfungsi karena vektor tidak lupa saat runtime tentang jenis objek yang dipegangnya. (tidak perlu untuk tipe parametrik).
Saya mencoba memperkenalkan banyak cara kode dievaluasi dalam Common Lisp serta contoh-contoh analisis statis yang mungkin (ini adalah SBCL). Contoh sandbox mengkompilasi sebagian kecil kode Lisp yang diambil dari file terpisah. Agar cukup aman, saya mengubah readtable, hanya mengizinkan subset dari simbol standar dan membungkus hal-hal dengan batas waktu.
Tidak ada yang di atas "tidak mungkin" dilakukan dengan bahasa lain. Pendekatan plug-in di Blender, dalam perangkat lunak musik atau IDE untuk bahasa yang dikompilasi secara statis yang melakukan kompilasi langsung, dll. Alih-alih alat eksternal, bahasa dinamis lebih memilih alat yang menggunakan informasi yang sudah ada. Semua penelepon FOO yang dikenal? semua subkelas BAR? semua metode yang dikhususkan oleh kelas ZOT? ini adalah data yang diinternalisasi. Jenis hanyalah salah satu aspek dari ini.
(lihat juga: CFFI )
sumber
Jawaban singkat: tidak, karena kesetaraan Turing.
Jawaban panjang: Orang ini menjadi troll. Memang benar bahwa sistem tipe "membatasi Anda untuk sebuah himpunan bagian," hal-hal di luar bagian itu, menurut definisi, hal-hal yang tidak berfungsi.
Apa pun yang dapat Anda lakukan dalam bahasa pemrograman Turing lengkap (yang merupakan bahasa yang dirancang untuk pemrograman tujuan umum, ditambah banyak yang tidak; itu adalah bar yang sangat rendah untuk dihapus dan ada beberapa contoh sistem menjadi Turing- lengkap tanpa disengaja) Anda dapat melakukan dalam bahasa pemrograman Turing-lengkap lainnya. Ini disebut "Turing equivalence," dan itu hanya berarti persis apa yang dikatakannya. Yang penting, itu tidak berarti bahwa Anda dapat melakukan hal lain dengan mudah dalam bahasa lain - beberapa orang akan berpendapat bahwa itulah inti dari menciptakan bahasa pemrograman baru: untuk memberi Anda cara yang lebih baik untuk melakukan tertentu hal-hal yang menyedot bahasa yang ada.
Sistem tipe dinamis, misalnya, dapat ditiru di atas sistem tipe OO statis dengan hanya mendeklarasikan semua variabel, parameter, dan mengembalikan nilai sebagai
Object
tipe dasar dan kemudian menggunakan refleksi untuk mengakses data tertentu di dalam, jadi ketika Anda menyadari ini Anda melihat bahwa secara harfiah tidak ada yang dapat Anda lakukan dalam bahasa dinamis yang tidak dapat Anda lakukan dalam bahasa statis. Tetapi melakukannya dengan cara seperti itu akan sangat berantakan, tentu saja.Pria dari kutipan itu benar bahwa tipe statis membatasi apa yang dapat Anda lakukan, tapi itu fitur penting, bukan masalah. Garis-garis di jalan membatasi apa yang dapat Anda lakukan di mobil Anda, tetapi apakah Anda menganggapnya terbatas, atau membantu? (Saya tahu saya tidak akan mau mengendarai mobil di jalan yang sibuk dan kompleks di mana tidak ada yang memberi tahu mobil-mobil pergi ke arah yang berlawanan untuk tetap di sisi mereka dan tidak datang ke tempat saya mengemudi!) Dengan membuat aturan yang dengan jelas menggambarkan apa dianggap perilaku yang tidak valid dan memastikan bahwa itu tidak akan terjadi, Anda sangat mengurangi kemungkinan terjadinya kecelakaan parah.
Juga, dia salah mengidentifikasi sisi lain. Bukannya "semua program menarik yang ingin Anda tulis akan berfungsi sebagai tipe", melainkan "semua program menarik yang ingin Anda tulis akan membutuhkan tipe." Setelah Anda melampaui tingkat kerumitan tertentu, menjadi sangat sulit untuk mempertahankan basis kode tanpa sistem tipe untuk membuat Anda sejalan, karena dua alasan.
Pertama, karena kode tanpa anotasi jenis sulit dibaca. Pertimbangkan Python berikut:
Apa yang Anda harapkan dari data yang terlihat seperti yang diterima sistem di ujung koneksi yang lain? Dan jika itu menerima sesuatu yang tampak sangat salah, bagaimana Anda mengetahui apa yang terjadi?
Itu semua tergantung pada struktur
value.someProperty
. Tapi seperti apa bentuknya? Pertanyaan bagus! Memanggil apasendData()
? Apa yang lewat? Seperti apa variabel itu? Dari mana asalnya? Jika ini bukan lokal, Anda harus menelusuri seluruh sejarahvalue
untuk melacak apa yang terjadi. Mungkin Anda melewati sesuatu yang juga memilikisomeProperty
properti, tetapi tidak melakukan apa yang Anda pikirkan?Sekarang mari kita lihat dengan anotasi jenis, seperti yang mungkin Anda lihat dalam bahasa Boo, yang menggunakan sintaksis yang sangat mirip tetapi diketik secara statis:
Jika ada yang tidak beres, tiba-tiba tugas debugging Anda menjadi lebih mudah: lihat definisi
MyDataType
! Plus, kemungkinan mendapatkan perilaku buruk karena Anda melewati beberapa jenis yang tidak kompatibel yang juga memiliki properti dengan nama yang sama tiba-tiba menjadi nol, karena sistem jenis tidak akan membiarkan Anda melakukan kesalahan itu.Alasan kedua didasarkan pada yang pertama: dalam proyek besar dan kompleks, Anda kemungkinan besar mendapat banyak kontributor. (Dan jika tidak, Anda membangunnya sendiri untuk waktu yang lama, yang pada dasarnya adalah hal yang sama. Coba baca kode yang Anda tulis 3 tahun yang lalu jika Anda tidak percaya kepada saya!) Ini berarti Anda tidak tahu apa yang dulu melalui kepala orang yang menulis hampir semua bagian kode yang diberikan pada saat mereka menulisnya, karena Anda tidak ada di sana, atau tidak ingat apakah itu kode Anda sendiri dulu. Memiliki tipe deklarasi benar-benar membantu Anda memahami apa maksud kode itu!
Orang-orang seperti lelaki dalam kutipan sering salah mengartikan manfaat dari pengetikan statis sebagai tentang "membantu kompiler" atau "semua tentang efisiensi" di dunia di mana sumber daya perangkat keras yang hampir tak terbatas membuatnya semakin tidak relevan dengan setiap tahun yang lewat. Tetapi seperti yang telah saya tunjukkan, sementara manfaat-manfaat itu memang ada, manfaat utama ada pada faktor manusia, khususnya keterbacaan kode dan pemeliharaan. (Efisiensi tambahan tentu saja merupakan bonus yang bagus!)
sumber
Saya akan melangkah ke samping bagian 'pola' karena saya pikir itu beralih ke definisi apa yang merupakan pola dan tidak dan saya sudah lama kehilangan minat dalam perdebatan itu. Apa yang akan saya katakan adalah bahwa ada hal - hal yang dapat Anda lakukan dalam beberapa bahasa yang tidak dapat Anda lakukan dalam bahasa lain. Biar saya perjelas, saya tidak mengatakan ada masalah yang bisa Anda selesaikan dalam satu bahasa yang tidak bisa Anda selesaikan dalam bahasa lain. Mason sudah menunjukkan kelengkapan Turing.
Sebagai contoh, saya telah menulis sebuah kelas dengan python yang mengambil membungkus elemen DOM XML dan membuatnya menjadi objek kelas satu. Artinya, Anda dapat menulis kode:
dan Anda memiliki konten jalur itu dari objek XML yang diuraikan. agak rapi dan rapi, IMO. Dan jika tidak ada simpul kepala, itu hanya mengembalikan objek dummy yang tidak mengandung apa-apa kecuali objek dummy (kura-kura sepanjang jalan.) Tidak ada cara nyata untuk melakukan itu di, katakanlah, Jawa. Anda harus mengkompilasi kelas sebelumnya yang didasarkan pada beberapa pengetahuan tentang struktur XML. Mengesampingkan apakah ini ide yang baik, hal semacam ini benar-benar mengubah cara Anda memecahkan masalah dalam bahasa yang dinamis. Saya tidak mengatakan itu berubah dengan cara yang selalu selalu lebih baik. Ada beberapa biaya pasti untuk pendekatan dinamis dan jawaban Mason memberikan tinjauan yang layak. Apakah mereka pilihan yang baik tergantung pada banyak faktor.
Di samping catatan, Anda dapat melakukan ini di Jawa karena Anda dapat membangun juru bahasa python di Jawa . Fakta bahwa menyelesaikan masalah khusus dalam bahasa tertentu dapat berarti membangun juru bahasa atau sesuatu yang mirip dengan itu sering diabaikan ketika orang berbicara tentang kelengkapan Turing.
sumber
IDynamicMetaObjectProvider
, dan itu sangat sederhana di Boo. ( Berikut ini implementasi dalam kurang dari 100 baris, termasuk sebagai bagian dari pohon sumber standar di GitHub, karena semudah itu!)"IDynamicMetaObjectProvider"
? Apakah itu terkait dengandynamic
kata kunci C # ? ... yang secara efektif hanya mengetuk pengetikan dinamis ke C #? Tidak yakin argumen Anda valid jika saya benar.dynamic
dicapai dalam C #. "Refleksi dan pencarian kamus" terjadi saat runtime, bukan waktu kompilasi. Saya benar-benar tidak yakin bagaimana Anda dapat membuat case yang tidak menambahkan pengetikan dinamis ke bahasa. Maksud saya adalah paragraf terakhir Jimmy mencakup hal itu.Kutipan itu benar, tetapi juga sangat tidak jujur. Mari kita uraikan alasannya:
Ya tidak cukup. Sebuah bahasa dengan mengetik dinamis memungkinkan Anda untuk mengekspresikan apapun selama itu Turing lengkap , yang sebagian besar adalah. Sistem tipe itu sendiri tidak memungkinkan Anda mengekspresikan segalanya. Mari kita beri dia manfaat dari keraguan di sini.
Ini benar, tetapi perhatikan bahwa kita sekarang dengan tegas berbicara tentang apa yang diperbolehkan oleh sistem tipe , bukan apa bahasa yang menggunakan sistem tipe memungkinkan. Meskipun dimungkinkan untuk menggunakan sistem tipe untuk menghitung hal-hal pada waktu kompilasi, ini pada umumnya tidak menyelesaikan Turing (karena sistem tipe umumnya dapat dipilih), tetapi hampir semua bahasa yang diketik secara statis juga Turing lengkap dalam runtime-nya (bahasa yang diketik secara dependen adalah tidak, tapi saya tidak percaya kita membicarakannya di sini).
Masalahnya adalah bahwa bahasa jenis dinamis memang memiliki tipe statis. Kadang-kadang semuanya adalah string, dan lebih umum ada beberapa tagged union di mana setiap hal adalah sekumpulan properti atau nilai seperti int atau double. Masalahnya adalah bahwa bahasa statis dapat melakukan ini juga, secara historis itu agak clunkier untuk melakukan ini, tetapi bahasa yang diketik secara statis modern membuat ini cukup mudah dilakukan seperti menggunakan bahasa jenis dinamis, jadi bagaimana mungkin ada perbedaan dalam apa yang bisa dilihat oleh programmer sebagai program yang menarik? Bahasa statis memiliki serikat tag yang persis sama dengan jenis lainnya.
Untuk menjawab pertanyaan dalam judul: Tidak, tidak ada pola desain yang tidak dapat diimplementasikan dalam bahasa yang diketik secara statis, karena Anda selalu dapat menerapkan cukup dari sistem dinamis untuk mendapatkannya. Mungkin ada pola yang Anda dapatkan secara 'gratis' dalam bahasa yang dinamis; ini mungkin layak atau tidak layak untuk digunakan dengan kelemahan bahasa-bahasa tersebut untuk YMMV .
sumber
Pasti ada hal-hal yang hanya dapat Anda lakukan dalam bahasa yang diketik secara dinamis. Tapi mereka tidak harus desain yang bagus .
Anda dapat menetapkan bilangan bulat 5 lalu string
'five'
, atauCat
objek, ke variabel yang sama. Tetapi Anda hanya mempersulit pembaca kode Anda untuk mencari tahu apa yang terjadi, apa tujuan dari setiap variabel.Anda dapat menambahkan metode baru ke kelas Ruby library dan mengakses bidang privasinya. Mungkin ada kasus-kasus di mana peretasan seperti itu bisa berguna tetapi ini akan menjadi pelanggaran enkapsulasi. (Saya tidak keberatan menambahkan metode yang hanya mengandalkan antarmuka publik, tetapi tidak ada yang tidak dapat dilakukan metode ekstensi C # yang diketik secara statis.)
Anda bisa menambahkan bidang baru ke objek kelas orang lain untuk memberikan beberapa data tambahan dengannya. Tapi itu desain yang lebih baik untuk hanya membuat struktur baru, atau memperluas tipe aslinya.
Secara umum, semakin terorganisir Anda ingin kode Anda tetap, semakin sedikit keuntungan yang harus Anda ambil dari dapat secara dinamis mengubah definisi jenis atau menetapkan nilai dari berbagai jenis ke variabel yang sama. Tetapi kemudian kode Anda tidak berbeda dari apa yang dapat Anda capai dalam bahasa yang diketik secara statis.
Apa bahasa dinamis yang baik adalah gula sintaksis. Sebagai contoh, ketika membaca objek JSON deserialized Anda dapat merujuk ke nilai bersarang hanya
obj.data.article[0].content
- lebih rapi daripada mengatakanobj.getJSONObject("data").getJSONArray("article").getJSONObject(0).getString("content")
.Pengembang Ruby terutama dapat berbicara panjang lebar tentang sihir yang dapat dicapai dengan mengimplementasikan
method_missing
, yang merupakan metode yang memungkinkan Anda untuk menangani panggilan percobaan ke metode yang tidak dideklarasikan. Misalnya, ActiveRecord ORM menggunakannya sehingga Anda dapat melakukan panggilanUser.find_by_email('[email protected]')
tanpa harus mendeklarasikanfind_by_email
metode. Tentu saja itu bukan apa-apa yang tidak dapat dicapai sepertiUserRepository.FindBy("email", "[email protected]")
dalam bahasa yang diketik secara statis, tetapi Anda tidak dapat menyangkal kerapiannya.sumber
Pola Proksi Dinamis adalah cara pintas untuk mengimplementasikan objek proxy tanpa perlu satu kelas per jenis yang Anda perlu proxy.
Menggunakan ini,
Proxy(someObject)
membuat objek baru yang berperilaku sama dengansomeObject
. Tentunya Anda juga ingin menambahkan fungsionalitas tambahan, tetapi ini adalah dasar yang berguna untuk memulai. Dalam bahasa statis lengkap, Anda harus menulis satu kelas Proxy per jenis yang ingin Anda proksi atau menggunakan pembuatan kode dinamis (yang, diakui, termasuk dalam pustaka standar banyak bahasa statis, terutama karena perancang mereka sadar akan masalah yang tidak dapat dilakukan karena hal ini).Kasus penggunaan lain dari bahasa dinamis adalah apa yang disebut "tambalan monyet". Dalam banyak hal, ini adalah anti-pola daripada pola, tetapi dapat digunakan dengan cara yang bermanfaat jika dilakukan dengan hati-hati. Dan sementara tidak ada alasan teoritis patch monyet tidak dapat diimplementasikan dalam bahasa statis, saya belum pernah melihat yang benar-benar memilikinya.
sumber
iya nih , ada banyak pola dan teknik yang hanya mungkin dilakukan dalam bahasa yang diketik secara dinamis.
Monkey patching adalah teknik di mana properti atau metode ditambahkan ke objek atau kelas saat runtime. Teknik ini tidak mungkin dalam bahasa yang diketik secara statis karena ini berarti jenis dan operasi tidak dapat diverifikasi pada waktu kompilasi. Atau dengan kata lain, jika suatu bahasa mendukung tambalan-monyet, itu adalah definisi bahasa yang dinamis.
Dapat dibuktikan bahwa jika suatu bahasa mendukung tambalan monyet (atau teknik serupa untuk memodifikasi tipe saat runtime), itu tidak dapat secara statis diketik. Jadi itu bukan hanya batasan dalam bahasa yang ada saat ini, itu adalah batasan mendasar dari pengetikan statis.
Jadi kutipannya benar - lebih banyak hal yang mungkin dalam bahasa yang dinamis daripada dalam bahasa yang diketik secara statis. Di sisi lain, beberapa jenis analisis hanya mungkin dilakukan dalam bahasa yang diketik secara statis. Misalnya Anda selalu tahu operasi mana yang diizinkan pada tipe tertentu, yang memungkinkan Anda mendeteksi operasi ilegal pada tipe kompilasi. Tidak ada verifikasi seperti itu dalam bahasa yang dinamis ketika operasi dapat ditambahkan atau dihapus pada saat runtime.
Inilah sebabnya mengapa tidak ada yang "terbaik" dalam konflik antara bahasa statis dan dinamis. Bahasa statis melepaskan kekuatan tertentu pada saat runtime dengan imbalan jenis daya yang berbeda pada waktu kompilasi, yang mereka yakini mengurangi jumlah bug dan membuat pengembangan lebih mudah. Beberapa percaya bahwa pertukaran itu sepadan, yang lain tidak.
Jawaban lain berpendapat bahwa Turing-equivalence berarti segala sesuatu yang mungkin dalam satu bahasa adalah mungkin di semua bahasa. Tetapi ini tidak mengikuti. Untuk mendukung sesuatu seperti penambalan monyet dalam bahasa statis, Anda pada dasarnya harus mengimplementasikan sub-bahasa dinamis di dalam bahasa statis. Ini tentu saja mungkin, tetapi saya berpendapat Anda kemudian memprogram dalam bahasa dinamis yang tertanam, karena Anda juga kehilangan pemeriksaan tipe statis yang ada dalam bahasa host.
C # sejak versi 4 telah mendukung objek yang diketik secara dinamis. Jelas bahwa perancang bahasa melihat manfaat dari memiliki kedua jenis pengetikan yang tersedia. Tapi itu juga menunjukkan Anda tidak dapat memiliki kue dan makan saya juga: Ketika Anda menggunakan objek dinamis di C # Anda mendapatkan kemampuan melakukan sesuatu seperti patch monyet, tetapi Anda juga kehilangan verifikasi tipe statis untuk interaksi dengan objek-objek ini.
sumber
Iya dan tidak.
Ada situasi di mana programmer mengetahui tipe variabel dengan lebih presisi daripada kompiler. Compiler mungkin tahu bahwa sesuatu adalah Object, tetapi programmer akan tahu (karena invarian dari program) bahwa itu sebenarnya sebuah String.
Izinkan saya menunjukkan beberapa contoh ini:
Saya tahu itu
someMap.get(T.class)
akan mengembalikan aFunction<T, String>
, karena bagaimana saya membangun someMap. Tetapi Java hanya yakin bahwa saya memiliki sebuah Function.Contoh lain:
Saya tahu bahwa data.properties.rowCount akan menjadi referensi dan bilangan bulat yang valid, karena saya telah memvalidasi data terhadap suatu skema. Jika bidang itu hilang, pengecualian akan dilemparkan. Tetapi seorang kompiler hanya akan tahu bahwa apakah melempar pengecualian atau mengembalikan semacam JSONValue generik.
Contoh lain:
"II6s" mendefinisikan cara data menyandikan tiga variabel. Karena saya sudah menentukan formatnya, saya tahu tipe mana yang akan dikembalikan. Kompiler hanya akan tahu bahwa ia mengembalikan tuple.
Tema pemersatu dari semua contoh ini adalah bahwa pemrogram mengetahui tipe tersebut, tetapi sistem tipe level Java tidak akan dapat mencerminkan hal itu. Kompiler tidak akan tahu jenisnya, dan dengan demikian bahasa yang diketik secara statis tidak akan membiarkan saya memanggilnya, sedangkan bahasa yang diketik secara dinamis akan.
Itulah kutipan asli:
Saat menggunakan pengetikan dinamis, saya bisa menggunakan tipe turunan paling banyak yang saya tahu, bukan hanya tipe turunan yang paling diketahui sistem tipe bahasa saya. Dalam semua kasus di atas, saya memiliki kode yang secara semantik benar, tetapi akan ditolak oleh sistem pengetikan statis.
Namun, untuk kembali ke pertanyaan Anda:
Salah satu contoh di atas, dan memang contoh apa pun dari pengetikan dinamis dapat dibuat valid dalam pengetikan statis dengan menambahkan gips yang sesuai. Jika Anda tahu tipe kompiler Anda tidak, cukup beri tahu kompiler dengan memberikan nilai. Jadi, pada tingkat tertentu, Anda tidak akan mendapatkan pola tambahan dengan menggunakan pengetikan dinamis. Anda mungkin perlu melakukan lebih banyak untuk menjalankan kode yang diketik secara statis.
Keuntungan dari pengetikan dinamis adalah Anda cukup menggunakan pola-pola ini tanpa mengkhawatirkan fakta bahwa sulit untuk meyakinkan sistem tipe Anda tentang validitasnya. Itu tidak mengubah pola yang tersedia, itu hanya mungkin membuatnya lebih mudah untuk diterapkan karena Anda tidak perlu mencari cara untuk membuat sistem tipe Anda mengenali pola atau menambahkan gips untuk menumbangkan sistem tipe.
sumber
data = parseJSON<SomeSchema>(someJson); print(data.properties.rowCount);
dan jika seseorang tidak memiliki kelas untuk deserialize ke kita dapat kembali kedata = parseJSON(someJson); print(data["properties.rowCount"]);
- yang masih diketik dan mengekspresikan maksud yang sama.data.properties
adalah objek dan saya tahu itudata.properties.rowCount
adalah bilangan bulat dan saya hanya bisa menulis kode yang menggunakannya. Usulandata["properties.rowCount"]
Anda tidak memberikan hal yang sama.Berikut adalah beberapa contoh dari Objective-C (diketik secara dinamis) yang tidak mungkin di C ++ (diketik secara statis):
Menempatkan objek dari beberapa kelas yang berbeda ke dalam wadah yang sama.
Tentu saja, ini membutuhkan inspeksi tipe runtime untuk kemudian menginterpretasikan isi dari wadah, dan sebagian besar teman dari pengetikan statis akan keberatan bahwa Anda seharusnya tidak melakukan ini sejak awal. Tetapi saya telah menemukan bahwa, di luar perdebatan agama, ini bisa berguna.
Memperluas kelas tanpa subclassing.
Di Objective-C, Anda bisa mendefinisikan fungsi anggota baru untuk kelas yang ada, termasuk yang seperti bahasa
NSString
. Misalnya, Anda dapat menambahkan metodestripPrefixIfPresent:
, sehingga Anda dapat mengatakan[@"foo/bar/baz" stripPrefixIfPresent:@"foo/"]
(perhatikan penggunaanNSSring
literal@""
).Penggunaan panggilan balik berorientasi objek.
Dalam bahasa yang diketik secara statis seperti Java dan C ++, Anda harus berusaha cukup lama untuk memungkinkan pustaka memanggil anggota sewenang-wenang dari objek yang disediakan pengguna. Di Jawa, solusinya adalah pasangan antarmuka / adaptor plus kelas anonim, dalam C ++ solusinya biasanya berbasis template, yang menyiratkan bahwa kode perpustakaan harus diekspos ke kode pengguna. Di Objective-C, Anda hanya meneruskan referensi objek plus pemilih untuk metode ke pustaka, dan pustaka dapat dengan mudah dan langsung memanggil kembali.
sumber
void*
sendiri bukan pengetikan dinamis, ini kurang pengetikan. Tapi ya, dynamic_cast, tabel virtual dll. Membuat C ++ tidak diketik secara statis. Apakah itu buruk?void*
ke beberapa jenis objek tertentu. Yang pertama menghasilkan kesalahan runtime jika Anda mengacaukan, hasil kemudian dalam perilaku yang tidak terdefinisi.