Ah, bu soruyu elimden geldiğince cevaplamaya çalışmaktan heyecan duyuyorum. Umarım düşüncelerimi düzgün bir şekilde alabilirim.
@Doval'ın bahsettiği ve sorgulayanın (kabaca da olsa) belirttiği gibi, gerçekten bir tip sisteminiz yok. Genel olarak daha zayıf ve ayrıca daha az ilginç olan etiketleri kullanan bir dinamik kontroller sisteminiz var.
“Bir tür sistemi nedir” sorusu oldukça felsefi olabilir ve konuyla ilgili farklı bakış açıları olan bir kitabı doldurabiliriz. Ancak, bu programcılar için bir site olduğu için cevabımı olabildiğince pratik tutmaya çalışacağım (ve gerçekten de, bazılarının düşündüğüne rağmen, programlamada türler oldukça pratiktir).
genel bakış
Daha formel temellere dalmadan önce, bir koltuk tipi bir sistemin ne için iyi olduğunu anlamasıyla başlayalım. Bir tür sistem, programlarımıza yapı yükler . Bize çeşitli fonksiyonları ve ifadeleri nasıl bir araya getirebileceğimizi anlatıyorlar. Yapısız, programlar kırılmaz ve çılgınca karmaşıktır, programcının en küçük bir hatasında zarar vermeye hazırdır.
Tip sistemli programlar yazmak, nane koşullarında dikkatli olmak gibidir - frenler çalışır, kapılar emniyetli bir şekilde kapanır, motor yağlanır vb. Tipsiz bir sistem olmadan programlar yazmak, kasksız ve tekerlekli bir motorla sürmek gibidir. spagetti dışında. Senin üzerinde kesinlikle hiçbir kontrol yok.
Tartışma toprağa, en biz edebi ifadesi ile bir dil var diyelim num[n]
ve str[s]
bu rakamı n ve dize s sırasıyla ve ilkel fonksiyonlarını temsil plus
ve concat
amaçlanan anlam. Açıkçası, plus "hello" "world"
veya gibi bir şey yazabilmek istemezsiniz concat 2 4
. Fakat bunu nasıl önleyebiliriz? Bir öncekine göre , 2 sayısını sayısal "dünya" dizesinden ayırmak için hiçbir yöntem yoktur. Söylemek istediğimiz, bu ifadelerin farklı bağlamlarda kullanılması gerektiği; farklı türleri var.
Dil ve Türleri
Biraz geri adım atalım: programlama dili nedir? Genel olarak, bir programlama dilini iki katmana ayırabiliriz: sözdizimi ve anlambilim. Bunlara sırasıyla statik ve dinamik denir . Bu iki bölüm arasındaki etkileşime aracılık etmek için tip sisteminin gerekli olduğu ortaya çıktı.
Sözdizimi
Bir program bir ağaçtır. Bilgisayara yazdığınız metin satırlarına aldanmayın; bunlar sadece bir programın insan tarafından okunabilir gösterimleridir . Programın kendisi bir Soyut Sözdizimi Ağacı . Örneğin, C'ye şunu yazabiliriz:
int square(int x) {
return x * x;
}
Programın somut sözdizimi budur (parça). Ağaç gösterimi:
function square
/ | \
int int x return
|
times
/ \
x x
Bir programlama dili , o dilin geçerli ağaçlarını tanımlayan bir dilbilgisi sağlar (somut veya soyut sözdizimi kullanılabilir). Bu genellikle BNF notasyonu gibi bir şey kullanılarak yapılır. Bunu, yarattığın dil için yaptığını farz ediyorum.
semantik
Tamam, programın ne olduğunu biliyoruz, ancak bu sadece statik bir ağaç yapısı. Muhtemelen, programımızın aslında bir şeyi hesaplamasını istiyoruz . Anlamsallığa ihtiyacımız var.
Programlama dillerinin anlambilimi zengin bir çalışma alanıdır. Genel olarak konuşursak, iki yaklaşım vardır: terimsel anlambilim ve işlemsel anlam . Anlamsal anlambilim, bir programı temel bir matematiksel yapıya (örneğin, doğal sayılar, sürekli fonksiyonlar, vb.) Eşleştirerek tanımlar. Bu programımıza anlam kazandırır. İşlemsel anlambilim, aksine, bir programın nasıl yürüdüğünü ayrıntılandırarak tanımlar. Bence operasyonel anlambilim, programcılar için (kendim de dahil) daha sezgiseldir, o yüzden buna devam edelim.
Resmi bir operasyonel anlambilimin nasıl tanımlanacağına bakmayacağım (detaylar biraz dahil), fakat temel olarak, aşağıdaki gibi kurallar istiyoruz:
num[n]
bir değer
str[s]
bir değer
- Eğer
num[n1]
ve num[n2]
tamsayıları n_1$ and $n_2$, then
artı olarak değerlendirirseniz (num [n1], num [n2]) `$ n_1 + n_2 $ tamsayısını değerlendirir.
- Eğer
str[s1]
ve str[s2]
s1 ve s2 dizgilerini concat(str[s1], str[s2])
değerlendirirse , o zaman s1s2 dizgisini değerlendirir.
Vb kurallar pratikte çok daha resmi, ama sen özü olsun. Ancak, yakında bir sorunla karşılaşıyoruz. Aşağıdakileri yazdığımızda ne olur:
concat(num[5], str[hello])
Hm. Bu tam bir bilmecedir. Bir sayıyı bir dizeyle birleştirmek için hiçbir yerde bir kural tanımlamamıştık. Böyle bir kural oluşturmayı deneyebiliriz, ancak bu işlemin anlamsız olduğunu sezgisel olarak biliyoruz. Bu programın geçerli olmasını istemiyoruz. Ve böylece kaçınılmaz olarak türlere yönlendiriliriz.
Türleri
Program, bir dilin dilbilgisi tarafından tanımlanan bir ağaçtır. Programlara yürütme kuralları ile anlam verilmiştir. Ancak bazı programlar yürütülemiyor; yani, bazı programlar anlamsızdır . Bu programlar kötü yazılmış. Böylece, yazmak, bir dilde anlamlı programları karakterize eder. Bir program iyi yazılmışsa, onu çalıştırabiliriz.
Bazı örnekler verelim. Yine değerlendirme kurallarında olduğu gibi, yazım kurallarını da gayrı resmi olarak sunacağım, ancak bunlar titizlikle yapılabilir. İşte bazı kurallar:
- Formun bir belirteci
num[n]
türü vardır nat
.
- Formun bir belirteci
str[s]
türü vardır str
.
- İfadenin
e1
türü nat
ve ifadesinin e2
türü nat
varsa, ifadenin plus(e1, e2)
türü vardır nat
.
- İfadenin
e1
türü str
ve ifadesinin e2
türü varsa str
, ifadenin concat(e1, e2)
türü vardır str
.
Bu nedenle, bu kurallara göre bir plus(num[5], num[2])
tür vardır nat
, ancak bir tür atayamayız plus(num[5], str["hello"])
. Bir programın (veya ifadenin) herhangi bir tür atayabiliyorsak iyi yazılmış olduğunu ve aksi takdirde yanlış yazılmış olduğunu söylüyoruz. A tipi sistemidir ses tüm iyi daktilo programlar çalıştırılabilir eğer. Haskell sestir; C değil.
Sonuç
Tiplerle ilgili başka görüşler var. Bir anlamda türler sezgisel mantığa karşılık gelir ve ayrıca kategori teorisinde nesneler olarak da görülebilirler. Bu bağlantıları anlamak büyüleyicidir, ancak yalnızca bir programlama dili yazmak veya hatta tasarlamak istemeniz şart değildir. Ancak program oluşumları kontrol etmek için bir araç olarak türlerini anlamak olduğunu programlama dili tasarımı ve geliştirilmesi için gerekli. Ne tür ifade edebileceğinin yüzeyini çizdim. Umarım, kendi dilinize katılabilecek kadar değerli olduğunu düşünürsünüz.