Apa contoh non-buat dari pengecekan tipe statis yang terlalu konservatif?

9

Dalam Konsep dalam Bahasa Pemrograman , John Mitchell menulis bahwa pengecekan tipe statis harus konservatif (terlalu ketat) karena Masalah Pemutusan Hubungan. Dia memberi contoh:

if (complicated-expression-that-could-run-forever)
   then (expression-with-type-error)
   else (expression-with-type-error)

Bisakah seseorang memberikan jawaban yang tidak dibuat-buat yang benar-benar menjadi masalah praktis?

Saya mengerti bahwa Java memungkinkan gips yang diperiksa secara dinamis untuk kasus-kasus seperti ini:

if (foo instanceof Person) {
    Person p = (Person) foo;
    :
}

tapi saya menganggap perlunya lebih banyak kekurangan bahasa / kompiler Java daripada masalah lintas-bahasa.

Ellen Spertus
sumber
2
Contoh Java yang Anda berikan adalah contoh non-buat dari pengecekan tipe statis yang terlalu konservatif. Dengan kata lain: jawabannya tergantung pada sistem jenis apa yang ada dalam pikiran Anda. Untuk setiap contoh yang kami tunjukkan, akan selalu ada sistem tipe yang dapat menangani contoh itu (sistem tipe tidak terlalu konservatif pada contoh itu). Untuk sistem tipe apa pun, kita selalu dapat menemukan contoh yang terlalu konservatif. Jadi, saya pikir Anda perlu menentukan jenis sistemnya. Jika sistem tipe Java tidak sesuai dengan yang Anda pikirkan, apakah ada sesuatu yang lebih spesifik yang Anda pikirkan? Jenis inferensi tipe ML?
DW
orang mungkin berpendapat bahwa contohnya adalah salah satu dari analisis kode statis menjadi "konservatif", bukan memeriksa jenis nec. akan sangat membantu untuk mendefinisikan "konservatif" . bisa dibilang semua sistem tipe statis akan "konservatif" dibandingkan dengan sistem dinamis karena yang pertama lebih ketat pada waktu kompilasi menurut definisi. Namun orang mungkin berpendapat keduanya tidak lebih ketat pada saat runtime karena pemeriksaan dinamis dapat mengembalikan kesalahan yang serupa (berbasis tipe) juga. dan omong-omong, gips yang diperiksa dinamis runtime dalam bahasa bukan kekurangan , mereka dalam bahasa yang paling dicek secara statis, mungkin terbukti tidak ada.
vzn

Jawaban:

7

Saya selalu melihatnya lebih sebagai masalah kenyamanan, daripada tentang apakah suatu algoritma bisa atau tidak bisa diungkapkan sama sekali. Jika saya benar-benar ingin menjalankan program seperti yang dibuat oleh Mitchell, saya hanya akan menulis simulator Turing Machine yang sesuai dalam bahasa yang diketik secara statis.

Trik dengan sistem tipe statis adalah menawarkan jenis fleksibilitas yang tepat hanya untuk kasus-kasus di mana fleksibilitas memungkinkan Anda untuk menulis kode yang lebih mudah dipelihara.

Berikut adalah beberapa contoh teknik penataan program yang kadang-kadang dianggap lebih mudah dikelola secara dinamis daripada bahasa yang diketik secara statis.

Generik dan Wadah

Dalam bahasa yang diketik secara statis sebelum ML (c. 1973) dan CLU (c. 1974) tidak sulit untuk membuat pohon string merah-hitam, pohon integer merah-hitam, pohon float merah-hitam, atau elemen pohon merah-hitam dari jenis tertentu Foo. Namun, sulit (mungkin mustahil) untuk membuat implementasi tunggal dari pohon merah-hitam yang keduanya diperiksa secara statis dan yang dapat menangani salah satu dari tipe data ini. Cara-cara di sekitar masalah adalah (1) untuk keluar dari sistem tipe sepenuhnya (misalnya: dengan menggunakanvoid * di C), (2) untuk menulis sendiri beberapa jenis preprocessor makro dan kemudian menulis makro yang menghasilkan kode untuk setiap jenis spesifik yang Anda inginkan atau (3) menggunakan pendekatan Lisp / Smalltalk (dan Java) untuk memeriksa jenis ekstraksi objek secara dinamis.

ML dan CLU memperkenalkan gagasan, masing-masing, tipe-tipe parameter yang disimpulkan dan dinyatakan secara eksplisit (statis), yang memungkinkan Anda untuk menulis tipe kontainer generik, yang diketik secara statis.

Subtipe Polimorfisme

Dalam bahasa yang diketik secara statis sebelum Simula67 (c. 1967) dan Hope (c. 1977), tidak mungkin untuk melakukan pengiriman dinamis dan secara statis memeriksa bahwa Anda telah membahas case untuk setiap subtipe. Banyak bahasa memiliki beberapa bentuk serikat tagged , tapi itu tanggung jawab programmer untuk memastikan bahwa mereka caseatau switchpernyataan, atau tabel melompat mereka, ditutupi setiap tag mungkin.

Bahasa yang mengikuti model Simula (C ++, Java, C #, Eiffel) menyediakan kelas abstrak dengan subkelas di mana kompiler dapat memeriksa bahwa setiap subkelas telah menerapkan semua metode yang dideklarasikan oleh kelas induk. Bahasa yang mengikuti model Harapan (semua varian ML, dari SML / NJ hingga Haskell) memiliki subtipe aljabar di mana kompiler dapat memeriksa bahwa setiap typecasepernyataan mencakup semua subtipe.

Monkey Patching dan Pemrograman Berorientasi Aspek

Sistem tipe dinamis membuat berbagai teknik prototyping jauh lebih mudah. Dalam bahasa di mana jenis diwakili oleh peta hash dari string ke fungsi (misalnya, Python, Javascript, Ruby) cukup mudah untuk secara global mengubah perilaku setiap modul yang bergantung pada jenis tertentu, hanya dengan secara dinamis memodifikasi peta hash yang mewakili bahwa Tipe.

Meskipun ada cara-cara yang jelas di mana tambalan monyet dapat digunakan untuk membuat program lebih sulit untuk dipelihara, ada juga cara di mana tambalan itu sebenarnya dapat digunakan untuk "baik" dan bukan "jahat". Khususnya dengan pemrograman berorientasi aspek, seseorang dapat menggunakan teknik seperti tambalan monyet untuk melakukan hal-hal seperti memodifikasi tipe file untuk menunjuk ke sistem file tervirtualisasi, memungkinkan pembangunan infrastruktur pengujian unit untuk "gratis", atau memodifikasi tipe pengecualian sederhana sehingga mereka cetak pesan log setiap kali mereka ditangkap untuk debuggability yang lebih baik.

Tidak seperti Generics dan Subtype Polymorphism di mana ide-ide kunci pemeriksaan statis tersedia di tahun 1970-an, pemeriksaan statis untuk pemrograman berorientasi aspek adalah (saya pikir) area penelitian aktif. Saya tidak tahu banyak tentang itu kecuali bahwa ada bahasa yang disebut AspectJ sejak sekitar 2001.

Logika Pengembaraan
sumber