Frasa seperti "pengetikan statis" dan "pengetikan dinamis" banyak digunakan, dan orang-orang cenderung menggunakan definisi yang agak berbeda, jadi mari kita mulai dengan mengklarifikasi apa yang kita maksudkan.
Pertimbangkan bahasa yang memiliki tipe statis yang diperiksa pada waktu kompilasi. Tetapi katakan bahwa kesalahan ketik hanya menghasilkan peringatan non-fatal, dan pada saat runtime, semuanya diketik bebek. Tipe statis ini hanya untuk kenyamanan programmer, dan tidak mempengaruhi codegen. Ini menggambarkan bahwa pengetikan statis tidak dengan sendirinya memaksakan batasan apa pun, dan tidak saling eksklusif dengan pengetikan dinamis. (Objective-C sangat banyak seperti ini.)
Tetapi kebanyakan sistem tipe statis tidak berperilaku seperti ini. Ada dua sifat umum dari sistem tipe statis yang dapat memaksakan batasan:
Kompiler dapat menolak program yang berisi kesalahan tipe statis.
Ini adalah batasan karena banyak program aman jenis tentu mengandung kesalahan jenis statis.
Sebagai contoh, saya memiliki skrip Python yang perlu dijalankan karena Python 2 dan Python 3. Beberapa fungsi mengubah tipe parameter mereka antara Python 2 dan 3, jadi saya punya kode seperti ini:
if sys.version_info[0] == 2:
wfile.write(txt)
else:
wfile.write(bytes(txt, 'utf-8'))
Pemeriksa tipe statis Python 2 akan menolak kode Python 3 (dan sebaliknya), meskipun itu tidak akan pernah dieksekusi. Program safe type saya mengandung kesalahan tipe statis.
Sebagai contoh lain, pertimbangkan program Mac yang ingin dijalankan pada OS X 10.6, tetapi manfaatkan fitur-fitur baru di 10.7. Metode 10.7 mungkin ada atau tidak ada saat runtime, dan ada pada saya, programmer, untuk mendeteksinya. Pemeriksa tipe statis dipaksa untuk menolak program saya untuk memastikan keamanan jenis, atau menerima program, bersama dengan kemungkinan menghasilkan kesalahan jenis (fungsi hilang) saat runtime.
Pemeriksaan tipe statis mengasumsikan bahwa lingkungan runtime dijelaskan dengan memadai oleh informasi waktu kompilasi. Tetapi memprediksi masa depan itu berbahaya!
Berikut ini satu batasan lagi:
Compiler dapat menghasilkan kode yang menganggap tipe runtime adalah tipe statis.
Dengan asumsi tipe statis "benar" memberikan banyak peluang untuk optimasi, tetapi optimasi ini dapat membatasi. Contoh yang baik adalah objek proxy, misalnya remoting. Katakanlah Anda ingin memiliki objek proxy lokal yang meneruskan pemanggilan metode ke objek nyata dalam proses lain. Akan lebih baik jika proxy itu generik (sehingga dapat menyamar sebagai objek apa pun) dan transparan (sehingga kode yang ada tidak perlu tahu itu berbicara ke proxy). Tetapi untuk melakukan ini, kompiler tidak dapat menghasilkan kode yang menganggap tipe statis sudah benar, misalnya dengan pemanggilan metode inlining secara statis, karena itu akan gagal jika objek sebenarnya adalah proxy.
Contoh dari tindakan remoting seperti itu termasuk NSXPCConnection milik ObjC atau TransparentProxy C # (yang implementasinya membutuhkan beberapa pesimisasi dalam runtime - lihat di sini untuk diskusi).
Ketika codegen tidak bergantung pada tipe statis, dan Anda memiliki fasilitas seperti penerusan pesan, Anda dapat melakukan banyak hal keren dengan objek proxy, debugging, dll.
Jadi itu adalah contoh dari beberapa hal yang dapat Anda lakukan jika Anda tidak diharuskan untuk memuaskan pemeriksa tipe. Batasan tidak dikenakan oleh tipe statis, tetapi oleh pemeriksaan tipe statis yang dipaksakan.