Bir tip sistemi nedir?


50

Arka fon

Bir yan proje olarak bir dil tasarlıyorum. Çalışan bir montajcıya, statik analizöre ve bunun için sanal makineye sahibim. Yaptığım altyapıyı kullanarak önemsiz programları derleyebildiğim ve çalıştırabildiğim için üniversitemde bir sunum yapmayı düşündüm.

Konuşmam sırasında VM'nin bir tip sistem sağladığını, " Tip sisteminiz ne için? " Diye sordum . Cevapladıktan sonra soruyu soran kişi tarafından güldüm.

Dolayısıyla, bu soruyu sorduğum için neredeyse kesinlikle itibarımı kaybedecek olsam da, Programcılara dönüyorum.

Benim anlayışım

Bunları anladığım kadarıyla, tip sistemleri bir programdaki varlıklar hakkında ek bilgi katmanı sağlamak için kullanılır, böylece çalışma zamanı veya derleyici veya başka herhangi bir makine parçası üzerinde çalıştığı bit dizeleriyle ne yapılacağını bilir. Ayrıca sözleşmelerin korunmasına da yardımcı olurlar - derleyici (veya kod analizörü veya çalışma zamanı veya başka bir program) programın herhangi bir noktada programcıların çalışmasını beklediği değerler üzerinde çalıştığını doğrulayabilir.

Bu insan programcılarına bilgi sağlamak için türler de kullanılabilir. Örneğin, bu bildirimi buluyorum:

function sqrt(double n) -> double;

bundan daha kullanışlı

sqrt(n)

İlki bol miktarda bilgi verir: sqrttanımlayıcının bir fonksiyon olduğu, bir doublegirdi olarak bir tek aldığı ve bir doubleçıktı olarak başka bir çıktı ürettiği . İkincisi, muhtemelen tek bir parametre alan bir fonksiyon olduğunu söyler.

Cevabım

Öyleyse, "Tip sisteminiz ne için?" Aşağıdaki gibi cevap verdim:

Tür sistemi dinamiktir (türler değerleri tutan, onları tutan değişkenlere atanmaz), ancak zorlayıcı kurallar olmadan güçlüdür (uyumsuz türleri temsil ettiği için tamsayıya dize ekleyemezsiniz, ancak kayan nokta sayısına tamsayı ekleyebilirsiniz) .

Tip sistemi, VM tarafından talimatlar için işlenenlerin geçerli olmasını sağlamak için kullanılır; ve programlayıcılar tarafından fonksiyonlarına iletilen parametrelerin geçerli olmasını sağlamak için kullanılabilir (yani doğru tipte).
Tip sistemi alt tiplemeyi ve çoklu kalıtımı destekler (her iki özellik de programcılar tarafından kullanılabilir) ve nesnelerin üzerindeki metotların dinamik olarak kullanılması durumunda tipler göz önünde bulundurulur - VM, hangi tip için hangi fonksiyonun belirli bir mesajın uygulandığını kontrol etmek için tipleri kullanır.

Takip eden soru, "Tür bir değere nasıl atanır?" İdi. Bu yüzden tüm değerlerin kutuda olduğunu ve türün adı, hangi mesajlara cevap verdiği ve hangi türden kalıtsal olduğu hakkında bilgi sağlayan bir tür tanım yapısına işaret eden bir göstergeye sahip olduğunu açıkladım.

Ondan sonra güldüm ve cevabım "Bu gerçek bir tip sistemi değil" yorumuyla reddedildi.

Öyleyse - tanımladığım şey "gerçek bir tip sistemi" olarak nitelenmezse, ne olurdu? Bu kişi sağladığım şeyin bir tip sistemi olarak kabul edilemeyeceği konusunda haklı mıydı?


19
İnsanlar tip sistemleri hakkında konuştuğunda genellikle statik yazma hakkında konuşurlar. Dinamik yazma, yazım sistemlerini önemseyen insanlar için çok ilginç değildir, çünkü neredeyse hiçbir şeyi garanti etmez. Örneğin x değişkeni ne tür bir değer tutabilir? Herhangi bir şey.
Doval,

7
Tepkilerini savunmak / açıklamak için ne söyleyeceklerini duymayı merak ediyorum.
Newtopian

18
@Doval Dinamik yazma, kedinize 5 eklemek gibi bir şey yaparak saçma bir duruma girmemenizi garanti edebilir. Elbette, denemenizi engellemeyecek , ama en azından gerçekten gerçekleşmesini engelleyebilir ve neyin yanlış gittiğini anlama ve düzeltici eylemler yapma, gerçekten yazılmaz bir dilin yapamayacağı şeyler yapma şansı verebilir.
8,

10
Kişi, "Tür bir değere nasıl atanır?" Sorusuna cevabınızı verdi. Kutu ve işaretçi diyagramlarını değil, yazım kurallarını duymak istediler. Gülmek olsa da, kesinlikle kaba.
gardenhead

10
Gülen kişi büyük olasılıkla, güçlü bir tür sistemi (Haskell popüler gibi) olan bazı diller (aile) için bir zealottur ve bundan daha az güçlü (ve dolayısıyla bir oyuncak) bundan daha az güçlü (ve dolayısıyla pratik olmayan) alay eder. ya da sadece farklı. Zealotlarla tartışmak tehlikeli ve boşuna. Öyle gülmek o kadar kaba ki böyle daha derin sorunları gösteriyor. Şanslısın, vaaz vermeye başlamadılar ...
hyde

Yanıtlar:


30

Tüm bunlar, ne tür sistemlerin sağladığının iyi bir açıklaması gibi görünüyor. Ve uygulamanız, yaptıkları için yeterince makul bir ses gibi görünüyor.

Bazı dillerde, diliniz çalışma zamanı gönderimi yapmadığından (veya vtables veya başka bir mekanizma aracılığıyla tekli gönderim yaptığınız için tür bilgisine gerek duymadığınız için) çalışma zamanı bilgisine ihtiyacınız olmaz. Bazı diller için, sadece bir sembol / yer tutucusuna sahip olmak yeterlidir, çünkü onun adını veya mirasını değil, sadece tür eşitliğini önemsersiniz.

Çevrenize bağlı olarak, kişi tip sisteminizde daha fazla formalizm istemiş olabilir. Programcıların ne yapabileceğini değil, onunla neyi kanıtlayabileceğini bilmek istiyorlar . Bu ne yazık ki akademi oldukça yaygındır. Her ne kadar akademisyenler böyle şeyler yaparlarsa da, tip sisteminizde bazı şeylerin doğruluktan kaçmalarına izin veren kusurlara sahip olmak oldukça kolaydır. Bunlardan birini tespit etmeleri mümkün.

Başka sorularınız varsa, Türler ve Programlama Dilleri konuyla ilgili kanonik kitaptır ve akademisyenlerin ihtiyaç duyduğu titizliğin bir kısmını ve bazı şeyleri tanımlamaya yardımcı olacak terminolojiyi öğrenmenize yardımcı olabilir.


3
"Ortamınıza bağlı olarak, kişi, tür sisteminizde daha fazla formalizm istemiş olabilir." Muhtemelen budur. Tip sistemi ile neyi ispatlayabileceğime odaklanmadım , bunun yerine bir araç olarak düşündüm. Kitap önerisi için teşekkürler!
Mael

1
@ Mael Bazı tip sistemler mantık olarak kullanılır ( mantıksal çerçevelere bakınız ). Bu nedenle, temel olarak tür, formülleri verir ve programlar, bu formüllerin kanıtlarıdır (örneğin, fonksiyon türü a -> b, b olarak görülebilir , yani bana bir tür değeri verirseniz, bir tür adeğeri elde edebilirsiniz b). Bununla birlikte, bunun tutarlı olması için dilin toplam olması ve dolayısıyla Turing'in tamamlanmamış olması gerekir. Dolayısıyla tüm gerçek yaşam tipi sistemler aslında tutarsız bir mantık tanımlar.
Bakuriu

20

@ Telastyn'in cevabını, özellikle biçimciliğe olan akademik ilgiye atıfta bulunduğundan dolayı seviyorum.

Tartışmaya eklememe izin verin.

Bir tip sistemi nedir?

Tip bir sistem, yasadışı program durumlarını tanımlayan, tespit eden ve önleyen bir mekanizmadır. Kısıtlamaları tanımlayarak ve uygulayarak çalışır. Sınır tanımları türlerdir ve sınır uygulamaları türlerin kullanımıdır , örneğin değişken bildirimde.

Tip tanımları tipik olarak kompozisyon operatörlerini (örneğin, yapılarda, alt sınıflarda olduğu gibi çeşitli bağlanma biçimlerini ve enums, sendikalarda olduğu gibi ayrılma şekillerini) destekler.

Türlerin kullanımındaki kısıtlamalar, bazen kompozisyon operatörlerine de izin verir (örneğin, en azından bu, tam olarak bu, ya bu ya da bu, başka bir şeyin tutulması şartıyla).

Yazım sistemi, dilde mevcutsa ve derleme zamanında, derleme zamanı hataları verebilmek amacıyla derleme zamanında uygulanmışsa, statik bir tip sistemdir; Bunlar, birçok yasadışı programın tek başına çalışmasına izin vermez, dolayısıyla yasa dışı program durumlarını engeller.

(Statik tip bir sistem, programın hakkında şikayet ettiği o unde edilmemiş koda ulaşacağı bilinir (veya belirlenemez) çalışmasını durdurur. ve programı çalışmadan önce hatayla değerlendirir.)

Çalışma zamanında bir tür sistemi uygulanırsa, yasadışı program durumlarını engelleyen dinamik bir tür sistemidir: ancak programı ilk sırada çalıştırılmasını önlemek yerine, orta sırada durdurarak.

Oldukça yaygın tipte bir sistem sunan, hem statik hem de dinamik özellikler sağlamaktır.


Hibrit tip sistemlerin hiç de yaygın olduğunu sanmıyorum. Aklında hangi dilleri var?
gardenhead,

2
@gardenhead, downcast yeteneği, statik tipte bir sistem özelliği değildir, bu nedenle genellikle çalışma zamanında dinamik olarak kontrol edilir.
Erik Eidt

1
@gardenhead: statik olarak yazılan dillerin çoğu çalışma zamanına yazma işlemini ertelemenize izin verir, basitçe C void *işaretçileri (çok zayıf), C # 'ın dinamik nesneleri veya Haskell'in varoluşsal olarak ölçülmüş GADT'leri (size çoğu zaman statik olarak yazılan değerlerden daha güçlü garantiler verir) Diller).
leftaroundabout

Doğru, "döküm" hakkında unuttum. Ancak döküm, zayıf tip bir sistem için sadece bir koltuk değneğidir.
gardenhead,

@gardenhead Dinamik seçenekler sunan statik dillerin yanı sıra, birçok dinamik dil de bazı statik yazmalar sağlar. Örneğin, Dart, Python ve Hack, hepsinde "kademeli yazma" konseptine dayalı statik analiz yapmak için modlar veya araçlar vardır.
IMSoP

14

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 plusve concatamaç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:

  1. num[n] bir değer
  2. str[s] bir değer
  3. Eğer num[n1]ve num[n2]tamsayıları n_1$ and $n_2$, thenartı olarak değerlendirirseniz (num [n1], num [n2]) `$ n_1 + n_2 $ tamsayısını değerlendirir.
  4. 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:

  1. Formun bir belirteci num[n]türü vardır nat.
  2. Formun bir belirteci str[s]türü vardır str.
  3. İfadenin e1türü natve ifadesinin e2türü natvarsa, ifadenin plus(e1, e2)türü vardır nat.
  4. İfadenin e1türü strve ifadesinin e2tü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.


4
+1. Şimdiye dek çektiğiniz dinamik yazma meraklılarının en büyük hilesi, dünyayı bir tür sistemi olmadan "tür" olabileceğine ikna etmekti. :-)
ruakh

1
Yana otomatik ilginç bir şey doğrulayamadığı keyfi programlar için, her tür sistemi dökme operatörü (ya da ahlaki eşdeğer) sağlamak zorundadır, aksi takdirde Turing tamlığı kurban eder. Bu elbette Haskell'i de içerir.
Kevin,

1
@Kevin Rice teoreminin farkındayım, ama olabileceği kadar alakalı değil. Başlangıçta, programların büyük bir çoğunluğu sınırsız özyineleme gerektirmez. Godel'in System T gibi yalnızca ilkel özyinelemeli bir dilde çalışıyorsak, durma dahil bir tür sistemi kullanarak ilginç özellikleri doğrulayabiliriz. Gerçek dünyadaki çoğu program oldukça basittir. Turing eksiksizliği abartılıyor.
gardenhead

9
“Dinamik yazma gerçekten de yazma değil” her zaman bana “Pop müzik gerçekten müzik değil” diyen klasik müzisyenler ya da “Katolikler gerçekten Hıristiyan değil” diyen Evanjelikler gibi görünüyordu. Evet, statik tip sistemler güçlü ve etkileyici ve önemlidir ve dinamik yazma farklı bir şeydir. Ancak (diğer cevapların tanımladığı gibi), geleneksel olarak tipik olarak adlandırılan ve hepsinde önemli ortaklıkları paylaşan statik tip sistemlerin ötesinde bir dizi faydalı şey vardır. Neden Bir Gerçek Yazma Olarak Bizim Türümüzün Yazılmasında Israr Etmek Gerekir?
Peter LeFanu Lumsdaine

5
@IMSoP: Bir kitaptan daha kısa bir şey için, Chris Smith'in makalesi Yazı sistemlerini tartışmadan önce bilmeniz gerekenler harika, dinamik yazmanın neden statik yazımdan oldukça farklı olduğunu ortaya koymak .
Peter LeFanu Lumsdaine
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.