Bahasa yang diketik secara dinamis tidak diketik
Membandingkan sistem tipe , tidak ada keuntungan dalam pengetikan dinamis. Pengetikan dinamis adalah kasus khusus pengetikan statis - pengetikan statis di mana setiap variabel memiliki tipe yang sama. Anda bisa mencapai hal yang sama di Java (minus conciseness) dengan membuat setiap variabel bertipe Object
, dan memiliki nilai "objek" bertipe Map<String, Object>
:
void makeItBark(Object dog) {
Map<String, Object> dogMap = (Map<String, Object>) dog;
Runnable bark = (Runnable) dogMap.get("bark");
bark.run();
}
Jadi, bahkan tanpa refleksi, Anda dapat mencapai efek yang sama di hampir semua bahasa yang diketik secara statis, selain kemudahan sintaksis. Anda tidak mendapatkan kekuatan ekspresif tambahan apa pun; sebaliknya, Anda memiliki kekuatan yang kurang ekspresif karena dalam bahasa yang diketik secara dinamis, Anda ditolak kemampuan untuk membatasi variabel ke jenis tertentu.
Membuat kulit bebek dalam bahasa yang diketik secara statis
Selain itu, bahasa yang diketik secara statis yang baik akan memungkinkan Anda untuk menulis kode yang berfungsi dengan semua jenis yang memiliki bark
operasi. Di Haskell, ini adalah kelas tipe:
class Barkable a where
bark :: a -> unit
Ini menyatakan kendala bahwa untuk beberapa jenis a
dianggap Barkable, harus ada bark
fungsi yang mengambil nilai jenis itu dan tidak mengembalikan apa pun.
Anda kemudian dapat menulis fungsi umum dalam Barkable
batasan:
makeItBark :: Barkable a => a -> unit
makeItBark barker = bark (barker)
Ini mengatakan bahwa makeItBark
akan bekerja untuk semua jenis Barkable
persyaratan yang memuaskan . Ini mungkin tampak mirip dengan interface
di Java atau C # tetapi memiliki satu keuntungan besar - tipe tidak harus menentukan di depan kelas tipe apa yang mereka puaskan. Saya dapat mengatakan bahwa tipe Duck
itu Barkable
kapan saja, bahkan jika Duck
tipe pihak ketiga saya tidak menulis. Sebenarnya, tidak masalah jika penulis Duck
tidak menulis suatu bark
fungsi - saya bisa menyediakannya setelah fakta ketika saya memberi tahu bahasa yang Duck
memuaskan Barkable
:
instance Barkable Duck where
bark d = quack (punch (d))
makeItBark (aDuck)
Ini mengatakan bahwa Duck
s dapat menggonggong, dan fungsi kulit mereka diimplementasikan dengan meninju bebek sebelum membuatnya dukun. Dengan cara itu, kita bisa memanggil makeItBark
bebek.
Standard ML
dan OCaml
bahkan lebih fleksibel karena Anda dapat memenuhi kelas tipe yang sama dalam lebih dari satu cara. Dalam bahasa-bahasa ini saya dapat mengatakan bahwa bilangan bulat dapat dipesan menggunakan pemesanan konvensional dan kemudian berbalik dan mengatakan mereka juga dapat dipesan oleh keterbelahan (misalnya 10 > 5
karena 10 dapat dibagi 5). Di Haskell, Anda hanya dapat membuat instance kelas tipe satu kali. (Ini memungkinkan Haskell untuk secara otomatis tahu bahwa itu ok untuk memanggil bark
pada bebek, dalam SML atau OCaml Anda harus eksplisit tentang yang bark
berfungsi Anda inginkan, karena mungkin ada lebih dari satu.)
Keringkasan yg padat isinya
Tentu saja, ada perbedaan sintaksis. Kode Python yang Anda sajikan jauh lebih ringkas daripada yang setara dengan Java yang saya tulis. Dalam praktiknya, keringkasan itu adalah bagian besar dari daya pikat bahasa yang diketik secara dinamis. Tetapi inferensi tipe memungkinkan Anda untuk menulis kode yang sama ringkasnya dalam bahasa yang diketik secara statis, dengan membebaskan Anda dari keharusan untuk secara eksplisit menulis jenis setiap variabel. Bahasa yang diketik secara statis juga dapat memberikan dukungan asli untuk pengetikan dinamis, menghilangkan verbositas dari semua casting dan manipulasi peta (misalnya C # 's dynamic
).
Program yang benar tetapi salah ketik
Agar adil, pengetikan statis harus mengesampingkan beberapa program yang secara teknis benar meskipun pemeriksa tipe tidak dapat memverifikasinya. Sebagai contoh:
if this_variable_is_always_true:
return "some string"
else:
return 6
Sebagian besar bahasa yang diketik secara statis akan menolak if
pernyataan ini , meskipun cabang lain tidak akan pernah muncul. Dalam praktiknya sepertinya tidak ada yang menggunakan jenis kode ini - apa pun yang terlalu pintar untuk pemeriksa tipe mungkin akan membuat pengelola kode masa depan Anda mengutuk Anda dan kerabat Anda berikutnya. Contohnya, seseorang berhasil menerjemahkan 4 proyek Python open source ke Haskell yang berarti mereka tidak melakukan apa pun yang tidak bisa dikompilasi oleh bahasa yang diketik secara statis. Terlebih lagi, kompiler menemukan beberapa bug terkait tipe yang tidak ditangkap oleh unit test.
Argumen terkuat yang pernah saya lihat untuk pengetikan dinamis adalah makro Lisp, karena mereka memungkinkan Anda untuk memperpanjang sintaks bahasa secara sewenang-wenang. Namun, Typed Racket adalah dialek Lisp yang diketik secara statis yang memiliki makro, jadi sepertinya pengetikan statis dan makro tidak saling eksklusif, meskipun mungkin lebih sulit untuk diterapkan secara bersamaan.
Apel dan Jeruk
Akhirnya, jangan lupa bahwa ada perbedaan yang lebih besar dalam bahasa daripada hanya sistem tipenya. Sebelum ke Java 8, melakukan segala jenis pemrograman fungsional di Jawa praktis tidak mungkin; lambda sederhana akan membutuhkan 4 baris kode kelas anonim boilerplate. Java juga tidak memiliki dukungan untuk kumpulan literal (mis [1, 2, 3]
.). Mungkin juga ada perbedaan dalam kualitas dan ketersediaan tooling (IDE, debugger), perpustakaan, dan dukungan komunitas. Ketika seseorang mengklaim lebih produktif dalam Python atau Ruby daripada Java, perbedaan fitur itu perlu diperhitungkan. Ada perbedaan antara membandingkan bahasa dengan semua baterai yang disertakan , inti bahasa dan sistem tipe .
makeItBark(collections.namedtuple("Dog", "bark")(lambda x: "woof woof"))
. Argumen itu bahkan bukan kelas , itu adalah anonim bernama tuple. Mengetik bebek ("jika dikuak seperti ...") memungkinkan Anda melakukan antarmuka ad hoc dengan dasarnya tidak ada batasan dan tidak ada overhead sintaksis. Anda dapat melakukan ini dalam bahasa seperti Java, tetapi Anda berakhir dengan banyak refleksi yang berantakan. Jika fungsi di Java memerlukan ArrayList dan Anda ingin memberikannya jenis koleksi lain, Anda SOL. Dengan python yang bahkan tidak bisa muncul.