Bahasa yang diketik secara dinamis yang saya tahu tidak pernah membiarkan pengembang menentukan jenis variabel, atau setidaknya memiliki dukungan yang sangat terbatas untuk itu.
JavaScript, misalnya, tidak menyediakan mekanisme apa pun untuk menegakkan jenis variabel saat nyaman untuk melakukannya. PHP membiarkan Anda menentukan beberapa jenis metode argumen, tetapi tidak ada cara untuk menggunakan jenis asli ( int
, string
, dll) untuk argumen, dan tidak ada cara untuk menegakkan jenis untuk apa pun selain argumen.
Pada saat yang sama, akan lebih mudah untuk memiliki pilihan untuk menentukan dalam beberapa kasus jenis variabel dalam bahasa yang diketik secara dinamis, daripada melakukan pemeriksaan jenis secara manual.
Mengapa ada batasan seperti itu? Apakah karena alasan teknis / kinerja (saya kira itu dalam kasus JavaScript), atau hanya karena alasan politik (yang, saya percaya, kasus PHP)? Apakah ini kasus untuk bahasa yang diketik secara dinamis lainnya yang saya tidak kenal?
Sunting: mengikuti jawaban dan komentar, berikut ini adalah contoh untuk klarifikasi: katakanlah kita memiliki metode berikut dalam PHP biasa:
public function CreateProduct($name, $description, $price, $quantity)
{
// Check the arguments.
if (!is_string($name)) throw new Exception('The name argument is expected to be a string.');
if (!is_string($description)) throw new Exception('The description argument is expected to be a string.');
if (!is_float($price) || is_double($price)) throw new Exception('The price argument is expected to be a float or a double.');
if (!is_int($quantity)) throw new Exception('The quantity argument is expected to be an integer.');
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Dengan beberapa upaya, ini dapat ditulis ulang sebagai (juga lihat Pemrograman dengan kontrak dalam PHP ):
public function CreateProduct($name, $description, $price, $quantity)
{
Component::CheckArguments(__FILE__, __LINE__, array(
'name' => array('value' => $name, 'type' => VTYPE_STRING),
'description' => array('value' => $description, 'type' => VTYPE_STRING),
'price' => array('value' => $price, 'type' => VTYPE_FLOAT_OR_DOUBLE),
'quantity' => array('value' => $quantity, 'type' => VTYPE_INT)
));
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Tetapi metode yang sama akan ditulis sebagai berikut jika PHP secara opsional akan menerima tipe asli untuk argumen:
public function CreateProduct(string $name, string $description, double $price, int $quantity)
{
// Check the arguments.
if (!$name) throw new Exception('The name argument cannot be an empty string.');
if ($price <= 0) throw new Exception('The price argument cannot be less or equal to zero.');
if ($price < 0) throw new Exception('The price argument cannot be less than zero.');
// We can finally begin to write the actual code.
// TODO: Implement the method here.
}
Yang mana yang lebih pendek untuk ditulis? Yang mana yang lebih mudah dibaca?
sumber
Jawaban:
Inti dari pengetikan statis adalah kemampuan untuk membuktikan secara statis bahwa program Anda benar dalam hal jenis (catatan: tidak sepenuhnya benar dalam semua hal). Jika Anda memiliki sistem tipe statis di seluruh, Anda dapat mendeteksi kesalahan tipe sebagian besar waktu.
Jika Anda hanya memiliki informasi jenis parsial, Anda hanya dapat memeriksa bagian kecil dari grafik panggilan tempat info jenis menjadi lengkap. Tetapi Anda telah menghabiskan waktu dan upaya untuk menentukan informasi jenis untuk bagian yang tidak lengkap, yang tidak dapat membantu Anda tetapi bisa memberikan rasa aman yang salah.
Untuk mengekspresikan informasi jenis, Anda memerlukan bagian bahasa yang tidak bisa terlalu sederhana. Anda akan segera mengetahui bahwa info seperti
int
tidak cukup; Anda akan menginginkan sesuatu sepertiList<Pair<Int, String>>
, kemudian tipe parametrik, dll. Ini dapat cukup membingungkan bahkan dalam kasus Jawa yang agak sederhana.Kemudian, Anda harus menangani informasi ini selama fase terjemahan dan fase eksekusi, karena itu konyol untuk hanya memeriksa kesalahan statis; pengguna akan berharap bahwa batasan tipe selalu berlaku jika ditentukan sama sekali. Bahasa dinamis tidak terlalu cepat, dan pemeriksaan seperti itu akan memperlambat kinerja lebih rendah. Bahasa statis dapat menghabiskan upaya serius memeriksa jenis karena hanya melakukannya sekali; bahasa yang dinamis tidak bisa.
Sekarang bayangkan menambahkan dan memelihara semua ini hanya agar orang kadang-kadang secara opsional menggunakan fitur-fitur ini, hanya mendeteksi sebagian kecil dari kesalahan jenis. Saya tidak berpikir itu sepadan dengan usaha.
Inti dari bahasa dinamis adalah untuk memiliki kerangka kerja yang sangat kecil dan sangat mudah ditempa, di mana Anda dapat dengan mudah melakukan hal-hal yang jauh lebih terlibat ketika dilakukan dalam bahasa statis: berbagai bentuk tambalan monyet yang digunakan untuk metaprogramming, mengejek dan pengujian, penggantian kode secara dinamis, dll. Smalltalk dan Lisp, keduanya sangat dinamis, membawanya sedemikian ekstrim untuk mengirimkan gambar lingkungan daripada membangun dari sumber. Tetapi ketika Anda ingin memastikan bahwa jalur data tertentu adalah tipe-aman, tambahkan pernyataan dan tulis lebih banyak tes unit.
sumber
Dalam sebagian besar bahasa dinamis, Anda setidaknya dapat menguji secara dinamis jenis objek atau nilai.
Dan ada inferencer tipe statis, dam dan / atau penegak untuk beberapa bahasa dinamis: mis
Dan Perl 6 akan mendukung sistem tipe opsional dengan pengetikan statis.
Tapi saya kira intinya adalah bahwa banyak orang menggunakan bahasa secara dinamis karena mereka diketik secara dinamis, dan bagi mereka pengetikan statis opsional sangat "ho hum". Dan banyak orang lain menggunakannya karena mereka "mudah bagi non-programmer untuk menggunakan", sebagian besar sebagai konsekuensi dari sifat dinamis dinamis yang pemaaf. Bagi mereka, pengetikan opsional adalah sesuatu yang mereka tidak akan mengerti, atau tidak akan terganggu untuk digunakan.
Jika Anda sinis, Anda dapat mengatakan bahwa pengetikan statis opsional menawarkan yang terburuk dari kedua dunia. Untuk zealot tipe statis, itu tidak mencegah semua kegagalan tipe dinamis. Untuk penggemar tipe dinamis, ini masih jaket lurus ... meskipun dengan tali tidak dikencangkan.
sumber
Javascript memang berencana untuk memasukkan beberapa pengetikan statis opsional, dan tampaknya seolah-olah banyak bahasa dinamis dewasa mengarah ke sana-
Alasannya adalah bahwa ketika Anda pertama kali kode, Anda ingin cepat dan diketik secara dinamis. Setelah kode Anda solid, berfungsi dan memiliki banyak kegunaan (r), Anda ingin mengunci desain untuk mengurangi kesalahan. (Ini bermanfaat bagi pengguna dan pengembang, karena yang pertama akan mendapatkan kesalahan memeriksa panggilan mereka dan yang terakhir tidak akan merusak hal-hal secara tidak sengaja.
Masuk akal bagi saya, karena saya biasanya menemukan ada terlalu banyak pengecekan tipe pada awal proyek, terlalu sedikit pada akhir masa hidup, tidak peduli bahasa apa yang saya gunakan;).
sumber
Objek Python memang memiliki tipe.
Anda menentukan jenis ketika Anda membuat objek.
Sebenarnya, pemeriksaan tipe manual dalam Python hampir selalu membuang-buang waktu dan kode.
Ini hanya praktik yang buruk untuk menulis kode periksa jenis dengan Python.
Jika jenis yang tidak pantas digunakan oleh beberapa sosiopat jahat, metode biasa Python akan menimbulkan pengecualian biasa ketika jenis itu gagal sesuai.
Anda tidak menulis kode, program Anda masih gagal dengan a
TypeError
.Ada kasus yang sangat jarang terjadi ketika Anda harus menentukan jenis pada saat run-time.
Karena ini bukan "batasan", pertanyaannya bukan pertanyaan nyata.
sumber
Sebagian besar waktu, Anda tidak perlu, setidaknya tidak pada tingkat detail yang Anda sarankan. Di PHP, operator yang Anda gunakan memperjelas apa yang Anda harapkan dari argumen; itu sedikit pengawasan desain meskipun PHP akan memberikan nilai-nilai Anda jika memungkinkan, bahkan ketika Anda melewatkan array ke operasi yang mengharapkan string, dan karena para pemain tidak selalu bermakna, Anda kadang-kadang mendapatkan hasil yang aneh ( dan ini adalah persis di mana jenis pemeriksaan yang berguna). Selain itu, tidak masalah jika Anda menambahkan bilangan bulat
1
dan5
atau string"1"
dan"5"
- fakta bahwa Anda menggunakan+
operator memberi sinyal ke PHP bahwa Anda ingin memperlakukan argumen sebagai angka, dan PHP akan patuh. Situasi yang menarik adalah ketika Anda menerima hasil kueri dari MySQL: Banyak nilai numerik hanya dikembalikan sebagai string, tetapi Anda tidak akan melihat karena PHP memberikannya untuk Anda setiap kali Anda memperlakukannya sebagai angka.Python sedikit lebih ketat tentang jenisnya, tetapi tidak seperti PHP, Python memiliki pengecualian sejak awal dan menggunakannya secara konsisten. Paradigma "lebih mudah untuk meminta maaf daripada izin" menyarankan untuk hanya melakukan operasi tanpa memeriksa jenis, dan mengandalkan pengecualian yang diajukan ketika jenis tidak masuk akal. Satu-satunya downside dari hal ini yang dapat saya pikirkan adalah bahwa kadang-kadang, Anda akan menemukan bahwa suatu jenis tidak sesuai dengan yang Anda harapkan, tetapi menemukan alasannya bisa membosankan.
Dan ada alasan lain untuk dipertimbangkan: Bahasa dinamis tidak memiliki tahap kompilasi. Bahkan jika Anda memiliki batasan tipe, mereka hanya bisa menyala saat runtime, hanya karena tidak ada waktu kompilasi . Jika cek Anda menyebabkan kesalahan runtime, akan lebih mudah untuk memodelkannya sesuai: Sebagai pemeriksaan eksplisit (seperti
is_XXX()
dalam PHP atautypeof
javascript), atau dengan melemparkan pengecualian (seperti yang dilakukan Python). Secara fungsional, Anda memiliki efek yang sama (kesalahan ditandai saat runtime ketika pemeriksaan tipe gagal), tetapi terintegrasi lebih baik dengan sisa semantik bahasa. Sangat tidak masuk akal untuk memperlakukan kesalahan tipe yang secara fundamental berbeda dari kesalahan runtime lainnya dalam bahasa yang dinamis.sumber
Anda mungkin tertarik dengan Haskell - sistemnya tipe menyimpulkan jenis dari kode, dan Anda dapat menentukan jenis juga.
sumber
Seperti jawaban lain yang disinggung, ada dua pendekatan untuk mengetik ketika mengimplementasikan bahasa pemrograman.
Kedua pendekatan itu valid, dan yang digunakan sebagian bergantung pada pertimbangan teknis seperti kinerja, dan sebagian lagi pada alasan politis seperti target pasar untuk bahasa tersebut.
sumber
Pertama-tama bahasa dinamis diciptakan terutama untuk kemudahan penggunaan. Seperti yang telah Anda sebutkan, sangat bagus untuk mengambil konversi tipe secara otomatis, dan memberikan kami lebih sedikit biaya tambahan. Tetapi pada saat yang sama kekurangan dalam masalah kinerja.
Anda dapat tetap menggunakan bahasa dinamis, jika Anda tidak mengkhawatirkan kinerja. Misalnya, JavaScript berjalan lebih lambat ketika harus melakukan banyak konversi jenis dalam program Anda, tetapi membantu mengurangi jumlah baris dalam kode Anda.
Dan untuk disebutkan, ada bahasa dinamis lain yang bahkan memungkinkan programmer untuk menentukan jenisnya. Misalnya Groovy adalah salah satu bahasa dinamis terkenal yang berjalan di JVM. Dan itu sudah sangat terkenal bahkan dalam beberapa hari terakhir. Perhatikan bahwa kinerja Groovy sama dengan Java.
Semoga ini bisa membantu Anda.
sumber
Tidak masuk akal untuk melakukannya.
Mengapa?
Karena sistem tipe DTL persis sehingga tipe tidak dapat ditentukan pada waktu kompilasi. Oleh karena itu, kompiler bahkan tidak dapat memeriksa bahwa jenis yang ditentukan masuk akal.
sumber
Lihatlah Go, pada permukaan itu diketik secara statis, tetapi jenis-jenis itu mungkin antarmuka yang pada dasarnya dinamis.
sumber