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]
dan str[s]
yang masing-masing mewakili n daneral s, dan fungsi primitif plus
dan concat
, dengan makna yang dimaksudkan. Jelas, Anda tidak ingin dapat menulis sesuatu seperti plus "hello" "world"
atau concat 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:
int square(int x) {
return x * x;
}
Itu adalah sintaks konkret untuk program (fragmen). Representasi pohon adalah:
function square
/ | \
int int x return
|
times
/ \
x x
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 nilai
str[s]
adalah sebuah nilai
- Jika
num[n1]
dan num[n2]
mengevaluasi ke integer n_1$ and $n_2$, then
plus (num [n1], num [n2]) `mengevaluasi ke integer $ n_1 + n_2 $.
- Jika
str[s1]
dan str[s2]
mengevaluasi ke string s1 dan s2, maka concat(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:
concat(num[5], str[hello])
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:
- Tanda bentuk
num[n]
memiliki tipe nat
.
- Tanda bentuk
str[s]
memiliki tipe str
.
- Jika ekspresi
e1
memiliki tipe nat
dan ekspresi e2
memiliki tipe nat
, maka ekspresi plus(e1, e2)
memiliki tipe nat
.
- Jika ekspresi
e1
memiliki tipe str
dan ekspresi e2
memiliki tipe str
, maka ekspresi concat(e1, e2)
memiliki tipe str
.
Jadi, menurut aturan ini, ada plus(num[5], num[2])
tipe is nat
, tetapi kami tidak dapat menetapkan tipe plus(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.