Latar Belakang
Saya merancang bahasa, sebagai proyek sampingan. Saya memiliki assembler yang berfungsi, analisa statis, dan mesin virtual untuk itu. Karena saya sudah dapat mengkompilasi dan menjalankan program non-sepele menggunakan infrastruktur yang saya bangun, saya berpikir untuk memberikan presentasi di universitas saya.
Selama pembicaraan saya, saya menyebutkan bahwa VM menyediakan sistem tipe, ditanya "Untuk apa sistem tipe Anda? ". Setelah menjawab saya ditertawakan oleh orang yang mengajukan pertanyaan.
Jadi, meskipun saya hampir pasti akan kehilangan reputasi karena mengajukan pertanyaan ini, saya beralih ke Programmer.
Pemahaman saya
Seperti yang saya pahami, sistem tipe digunakan untuk memberikan lapisan informasi tambahan tentang entitas dalam suatu program, sehingga runtime, atau kompiler, atau bagian mesin lainnya, tahu apa yang harus dilakukan dengan rangkaian bit yang beroperasi. Mereka juga membantu mempertahankan kontrak - kompiler (atau penganalisa kode, atau runtime, atau program lain) dapat memverifikasi bahwa pada titik tertentu program beroperasi pada nilai-nilai yang diharapkan programmer untuk beroperasi.
Jenis juga dapat digunakan untuk memberikan informasi kepada programmer manusia tersebut. Misalnya, saya menemukan deklarasi ini:
function sqrt(double n) -> double;
lebih bermanfaat dari yang ini
sqrt(n)
Yang pertama memberikan banyak informasi: bahwa sqrt
pengidentifikasi adalah fungsi, mengambil satu double
sebagai input, dan menghasilkan yang lain double
sebagai output. Yang terakhir memberitahu Anda bahwa itu mungkin fungsi yang mengambil parameter tunggal.
Jawabanku
Jadi, setelah ditanya, "Untuk apa sistem tipe Anda?" Saya menjawab sebagai berikut:
Sistem tipe bersifat dinamis (tipe ditugaskan ke nilai, bukan ke variabel yang menahannya), tetapi kuat tanpa aturan paksaan yang mengejutkan (Anda tidak dapat menambahkan string ke integer karena mereka mewakili tipe yang tidak kompatibel, tetapi Anda dapat menambahkan integer ke angka floating point) .
Sistem tipe digunakan oleh VM untuk memastikan bahwa operan untuk instruksi adalah valid; dan dapat digunakan oleh programmer untuk memastikan bahwa parameter yang diteruskan ke fungsinya valid (yaitu tipe yang benar).
Sistem tipe mendukung subtyping dan multiple inheritance (kedua fitur tersedia untuk programmer), dan tipe dipertimbangkan ketika pengiriman dinamis metode pada objek digunakan - VM menggunakan tipe untuk memeriksa dengan fungsi apa pesan yang diberikan diimplementasikan untuk tipe yang diberikan.
Pertanyaan tindak lanjut adalah "Dan bagaimana jenis ditugaskan ke nilai?". Jadi saya menjelaskan bahwa semua nilai dikotakkan, dan memiliki pointer yang menunjuk ke struktur definisi tipe yang memberikan informasi tentang nama tipe, pesan apa yang ditanggapi, dan tipe apa yang diwarisi darinya.
Setelah itu, saya ditertawakan, dan jawaban saya ditolak dengan komentar "Itu bukan sistem huruf yang nyata.".
Jadi - jika apa yang saya jelaskan tidak memenuhi syarat sebagai "sistem huruf nyata", apa yang akan terjadi? Apakah orang itu benar bahwa apa yang saya berikan tidak dapat dianggap sebagai sistem huruf?
Jawaban:
Itu semua tampak seperti deskripsi yang bagus tentang sistem tipe apa yang disediakan. Dan implementasi Anda kedengarannya cukup masuk akal untuk apa yang dilakukannya.
Untuk beberapa bahasa, Anda tidak akan memerlukan informasi runtime karena bahasa Anda tidak melakukan pengiriman runtime (atau Anda melakukan pengiriman tunggal melalui vtables atau mekanisme lain, jadi tidak perlu informasi jenis). Untuk beberapa bahasa, hanya memiliki simbol / placeholder sudah cukup karena Anda hanya peduli tentang kesetaraan jenis, bukan nama atau warisannya.
Tergantung pada lingkungan Anda, orang tersebut mungkin menginginkan lebih banyak formalisme dalam sistem tipe Anda. Mereka ingin tahu apa yang bisa Anda buktikan dengannya, bukan apa yang bisa dilakukan oleh programmer . Sayangnya ini cukup umum di dunia akademis. Meskipun para akademisi melakukan hal-hal seperti itu karena cukup mudah untuk memiliki kekurangan dalam sistem tipe Anda yang memungkinkan hal-hal lolos dari kebenaran. Mungkin saja mereka melihat salah satunya.
Jika Anda memiliki pertanyaan lebih lanjut, Jenis dan Bahasa Pemrograman adalah buku kanonik tentang subjek tersebut dan dapat membantu Anda mempelajari beberapa ketelitian yang dibutuhkan oleh para akademisi, serta beberapa terminologi untuk membantu menggambarkan berbagai hal.
sumber
a -> b
dapat dilihat sebagai b) , yaitu jika Anda memberi saya nilai tipea
saya bisa mendapatkan nilai tipeb
). Namun agar ini konsisten bahasa harus total, dan dengan demikian non-Turing lengkap. Jadi semua sistem tipe kehidupan nyata benar-benar mendefinisikan logika yang tidak konsisten.Saya suka jawaban @ Telastyn terutama karena referensi untuk kepentingan akademis dalam formalisme.
Izinkan saya untuk menambah diskusi.
Sistem tipe adalah mekanisme untuk mendefinisikan, mendeteksi, dan mencegah status program ilegal. Ia bekerja dengan mendefinisikan dan menerapkan kendala. Definisi kendala adalah tipe , dan, aplikasi kendala adalah penggunaan tipe , misalnya dalam deklarasi variabel.
Jenis definisi biasanya mendukung operator komposisi (misalnya berbagai bentuk konjungsi, seperti dalam struktur, subkelas, dan, disjungsi, seperti pada enum, serikat pekerja).
Kendala, penggunaan jenis, kadang-kadang juga memungkinkan operator komposisi (misalnya setidaknya ini, tepat ini, ini atau itu, ini asalkan ada sesuatu yang lain memegang).
Jika sistem tipe tersedia dalam bahasa dan diterapkan pada waktu kompilasi menuju tujuan untuk dapat mengeluarkan kesalahan waktu kompilasi, itu adalah sistem tipe statis; ini mencegah banyak program ilegal dari kompilasi apalagi berjalan, karenanya mencegah negara program ilegal.
(Suatu sistem tipe statis menghentikan suatu program dari menjalankan apakah diketahui atau tidak (atau tidak dapat dipastikan) bahwa program tersebut akan mencapai kode tidak sehat yang dikeluhkannya. Sistem tipe statis mendeteksi jenis omong kosong tertentu (pelanggaran terhadap batasan yang dinyatakan) dan menilai program salah sebelum dijalankan.)
Jika sistem tipe diterapkan pada saat runtime, itu adalah sistem tipe dinamis yang mencegah status program ilegal: tetapi dengan menghentikan program pada pertengahan proses, alih-alih mencegahnya berjalan di tempat pertama.
Penawaran jenis sistem yang cukup umum adalah menyediakan fitur statis dan dinamis.
sumber
void *
pointer C (sangat lemah), objek dinamis C #, atau GADT yang dikuantifikasi secara eksistensial Haskell (yang memberikan Anda jaminan yang lebih kuat daripada nilai yang diketik secara statis di sebagian besar lainnya. bahasa).Oh man, saya senang mencoba menjawab pertanyaan ini sebaik mungkin. Saya harap saya dapat mengatur pikiran saya dengan benar.
Seperti @Doval sebutkan dan penanya tunjukkan (walaupun kasar), Anda tidak benar-benar memiliki sistem tipe. Anda memiliki sistem pemeriksaan dinamis menggunakan tag, yang secara umum jauh lebih lemah, dan juga jauh lebih menarik.
Pertanyaan "apa itu sistem tipe" bisa sangat filosofis, dan kita bisa mengisi buku dengan sudut pandang yang berbeda tentang masalah ini. Namun, karena ini adalah situs untuk pemrogram, saya akan mencoba menjaga jawaban saya sepraktis mungkin (dan sungguh, tipe sangat praktis dalam pemrograman, terlepas dari apa yang mungkin dipikirkan oleh beberapa orang).
Gambaran
Mari kita mulai dengan memahami apa jenis sistem yang baik untuk sistem, sebelum menyelam ke dasar yang lebih formal. Sistem tipe memaksakan struktur pada program kami . Mereka memberi tahu kami bagaimana kami dapat menyambungkan berbagai fungsi dan ekspresi secara bersamaan. Tanpa struktur, program tidak dapat dipertahankan dan sangat rumit, siap untuk menyebabkan kerusakan pada kesalahan sekecil apa pun dari programmer.
Program menulis dengan sistem tipe seperti mengemudi dengan hati-hati dalam kondisi mint - rem bekerja, pintu tertutup dengan aman, mesin diminyaki, dll. Program menulis tanpa sistem jenis seperti mengendarai sepeda motor tanpa helm dan dengan roda yang dibuat keluar dari spageti. Anda sama sekali tidak memiliki kendali atas Anda.
Sebagai landasan diskusi, katakanlah kita memiliki bahasa dengan ekspresi literal
num[n]
danstr[s]
yang masing-masing mewakili n daneral s, dan fungsi primitifplus
danconcat
, dengan makna yang dimaksudkan. Jelas, Anda tidak ingin dapat menulis sesuatu sepertiplus "hello" "world"
atauconcat 2 4
. Tetapi bagaimana kita bisa mencegah ini? A priori , tidak ada metode untuk membedakan angka 2 dari string literal "dunia". Yang ingin kami katakan adalah bahwa ungkapan-ungkapan ini harus digunakan dalam konteks yang berbeda; mereka memiliki tipe yang berbeda.Bahasa dan Jenis
Mari mundur sedikit: apa itu bahasa pemrograman? Secara umum, kita dapat membagi bahasa pemrograman menjadi dua lapisan: sintaks dan semantik. Ini juga disebut statika dan dinamika . Ternyata sistem tipe ini diperlukan untuk memediasi interaksi antara dua bagian ini.
Sintaksis
Program adalah pohon. Jangan tertipu oleh baris teks yang Anda tulis di komputer; ini hanya representasi yang bisa dibaca manusia dari suatu program. Program itu sendiri adalah Pohon Sintaks Abstrak . Sebagai contoh, dalam C kita dapat menulis:
Itu adalah sintaks konkret untuk program (fragmen). Representasi pohon adalah:
Sebuah bahasa pemrograman menyediakan tata bahasa mendefinisikan pohon valid bahwa bahasa (baik beton atau sintaks abstrak dapat digunakan). Ini biasanya dilakukan dengan menggunakan sesuatu seperti notasi BNF. Saya berasumsi Anda telah melakukan ini untuk bahasa yang Anda buat.
Semantik
OK, kita tahu apa itu program, tapi itu hanya struktur pohon statis. Agaknya, kami ingin program kami benar-benar menghitung sesuatu. Kami membutuhkan semantik.
Semantik bahasa pemrograman adalah bidang studi yang kaya. Secara umum, ada dua pendekatan: semantik denotasi dan semantik operasional . Semantik denotasional menggambarkan suatu program dengan memetakannya ke dalam beberapa struktur matematika yang mendasarinya (misalnya bilangan asli, fungsi kontinu, dll). yang memberikan makna bagi program kami. Semantik operasional, sebaliknya, mendefinisikan program dengan merinci bagaimana dijalankannya. Menurut pendapat saya, semantik operasional lebih intuitif untuk programmer (termasuk saya), jadi mari kita tetap dengan itu.
Saya tidak akan membahas cara mendefinisikan semantik operasional formal (detailnya sedikit terlibat), tetapi pada dasarnya, kami ingin aturan seperti berikut:
num[n]
adalah sebuah nilaistr[s]
adalah sebuah nilainum[n1]
dannum[n2]
mengevaluasi ke integern_1$ and $n_2$, then
plus (num [n1], num [n2]) `mengevaluasi ke integer $ n_1 + n_2 $.str[s1]
danstr[s2]
mengevaluasi ke string s1 dan s2, makaconcat(str[s1], str[s2])
dievaluasi ke string s1s2.Dll. Aturannya dalam praktik jauh lebih formal, tetapi Anda mendapatkan intinya. Namun, kami segera mengalami masalah. Apa yang terjadi ketika kita menulis yang berikut ini:
Hm Ini cukup membingungkan. Kami belum menetapkan aturan di mana pun untuk cara menggabungkan angka dengan string. Kami dapat mencoba membuat aturan seperti itu, tetapi kami secara intuitif tahu bahwa operasi ini tidak ada artinya. Kami tidak ingin program ini valid. Dan dengan demikian kita dituntun ke jenis.
Jenis
Program adalah pohon sebagaimana didefinisikan oleh tata bahasa bahasa. Program diberi makna oleh aturan eksekusi. Tetapi beberapa program tidak dapat dijalankan; yaitu, beberapa program tidak ada artinya . Program-program ini salah ketik. Jadi, mengetik mencirikan program yang bermakna dalam suatu bahasa. Jika suatu program diketik dengan baik, kita dapat menjalankannya.
Mari kita beri beberapa contoh. Sekali lagi, seperti dengan aturan evaluasi, saya akan menyajikan aturan mengetik secara informal, tetapi mereka dapat dibuat ketat. Berikut ini beberapa aturan:
num[n]
memiliki tipenat
.str[s]
memiliki tipestr
.e1
memiliki tipenat
dan ekspresie2
memiliki tipenat
, maka ekspresiplus(e1, e2)
memiliki tipenat
.e1
memiliki tipestr
dan ekspresie2
memiliki tipestr
, maka ekspresiconcat(e1, e2)
memiliki tipestr
.Jadi, menurut aturan ini, ada
plus(num[5], num[2])
tipe isnat
, tetapi kami tidak dapat menetapkan tipeplus(num[5], str["hello"])
. Kami mengatakan sebuah program (atau ekspresi) diketik dengan baik jika kami dapat menetapkannya jenis apa pun, dan itu salah ketik. Sistem tipe adalah suara jika semua program yang diketik dengan baik dapat dieksekusi. Haskell adalah suara; C tidak.Kesimpulan
Ada pandangan lain tentang tipe. Jenis-jenis tertentu berhubungan dengan logika intuitionistic, dan mereka juga dapat dilihat sebagai objek dalam teori kategori. Memahami koneksi-koneksi ini menarik, tetapi tidak penting jika seseorang hanya ingin menulis atau bahkan mendesain bahasa pemrograman. Namun, memahami tipe sebagai alat untuk mengendalikan formasi program sangat penting untuk desain bahasa pemrograman, dan pengembangan. Saya hanya menggores permukaan jenis apa yang bisa mengekspresikan. Saya harap Anda berpikir mereka cukup bermanfaat untuk dimasukkan ke dalam bahasa Anda.
sumber